001/*
002 *  Copyright 2016 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.search.solr.schema;
017
018import java.util.HashMap;
019import java.util.Map;
020
021import org.apache.solr.client.solrj.request.schema.SchemaRequest;
022
023/**
024 * Represents a field definition in a solr schema.
025 */
026public class FieldDefinition implements SchemaDefinition
027{
028    /** The field name, can contain a star character to represent a dynamic field (i.e. *_type). */
029    protected String _name;
030    
031    /** The field type. */
032    protected String _type;
033    
034    /** If the field is multi-valued. */
035    protected boolean _multiValued;
036    
037    /** If the field is stored as docValues. */
038    protected boolean _docValues;
039    
040    /** Whether the field is indexed. */
041    protected boolean _indexed;
042    
043    /** Whether the field is stored. */
044    protected boolean _stored;
045    
046    /**
047     * Build a field definition, indexed and stored.
048     * @param name The field name, can contain a star character to represent a dynamic field (i.e. *_type).
049     * @param type The field type.
050     * @param multiValued <code>true</code> if the field is multi-valued.
051     * @param docValues <code>true</code> if the field is stored as docValues.
052     */
053    public FieldDefinition(String name, String type, boolean multiValued, boolean docValues)
054    {
055        this(name, type, multiValued, docValues, true, true);
056    }
057    
058    /**
059     * Build a field definition.
060     * @param name The field name, can contain a star character to represent a dynamic field (i.e. *_type).
061     * @param type The field type.
062     * @param multiValued <code>true</code> if the field is multi-valued.
063     * @param docValues <code>true</code> if the field is stored as docValues.
064     * @param indexed <code>true</code> if the field is indexed.
065     * @param stored <code>true</code> if the field is stored.
066     */
067    public FieldDefinition(String name, String type, boolean multiValued, boolean docValues, boolean indexed, boolean stored)
068    {
069        this._name = name;
070        this._type = type;
071        this._multiValued = multiValued;
072        this._docValues = docValues;
073        this._indexed = indexed;
074        this._stored = stored;
075    }
076    
077    /**
078     * Build a field definition from a map of attributes.
079     * @param attributes the Map of attributes.
080     */
081    public FieldDefinition(Map<String, Object> attributes)
082    {
083        this._name = (String) attributes.get("name");
084        this._type = (String) attributes.get("type");
085        this._multiValued = getBoolean(attributes, "multiValued", false);
086        this._docValues = getBoolean(attributes, "docValues", false);
087        this._indexed = getBoolean(attributes, "indexed", false);
088        this._stored = getBoolean(attributes, "stored", false);
089    }
090    
091    private boolean getBoolean(Map<String, Object> attributes, String name, boolean defaultValue)
092    {
093        String value = (String) attributes.get(name);
094        return value != null ? Boolean.parseBoolean(value) : defaultValue;
095    }
096    
097    /**
098     * Get the field name.
099     * @return The field name.
100     */
101    public String getName()
102    {
103        return _name;
104    }
105    
106    /**
107     * Set the field name.
108     * @param name the field name.
109     */
110    public void setName(String name)
111    {
112        this._name = name;
113    }
114    
115    /**
116     * Get the field type.
117     * @return The field type.
118     */
119    public String getType()
120    {
121        return _type;
122    }
123    
124    /**
125     * Set the field type.
126     * @param type the field type.
127     */
128    public void setType(String type)
129    {
130        this._type = type;
131    }
132    
133    /**
134     * If the field is multi-valued.
135     * @return true if the field is multi-valued, false otherwise.
136     */
137    public boolean isMultiValued()
138    {
139        return _multiValued;
140    }
141    
142    /**
143     * Set if the field is multi-valued.
144     * @param multiValued <code>true</code> if the field is multi-valued.
145     */
146    public void setMultiValued(boolean multiValued)
147    {
148        this._multiValued = multiValued;
149    }
150    
151    /**
152     * True to store the field as docValues.
153     * @return true to store the field as docValues, false otherwise.
154     */
155    public boolean isDocValues()
156    {
157        return _docValues;
158    }
159    
160    /**
161     * Set if the field is stored as docValues.
162     * @param docValues <code>true</code> if the field is stored as docValues.
163     */
164    public void setDocValues(boolean docValues)
165    {
166        this._docValues = docValues;
167    }
168    
169    /**
170     * True to store the field as indexed.
171     * @return true to store the field as indexed, false otherwise.
172     */
173    public boolean isIndexed()
174    {
175        return _indexed;
176    }
177    
178    /**
179     * Set if the field is stored as indexed.
180     * @param indexed <code>true</code> if the field is stored as indexed.
181     */
182    public void setIndexed(boolean indexed)
183    {
184        this._indexed = indexed;
185    }
186    
187    /**
188     * True to store the field as stored.
189     * @return true to store the field as stored, false otherwise.
190     */
191    public boolean isStored()
192    {
193        return _stored;
194    }
195    
196    /**
197     * Set if the field is stored as stored.
198     * @param stored <code>true</code> if the field is stored as stored.
199     */
200    public void setStored(boolean stored)
201    {
202        this._stored = stored;
203    }
204    
205    /**
206     * Get the attributes to build the field.
207     * @return the attributes as a map
208     */
209    protected Map<String, Object> _getAttributes()
210    {
211        // Force indexed and stored attributes to true.
212        Map<String, Object> attributes = new HashMap<>();
213        attributes.put("name", getName());
214        attributes.put("type", getType());
215        attributes.put("multiValued", isMultiValued());
216        attributes.put("docValues", isDocValues());
217        attributes.put("indexed", Boolean.TRUE);
218        attributes.put("stored", Boolean.TRUE);
219        return attributes;
220    }
221    
222    public SchemaRequest.Update getSchemaUpdate()
223    {
224        return new SchemaRequest.AddField(_getAttributes());
225    }
226    
227    public boolean exists(SchemaFields schemaFields)
228    {
229        return schemaFields.hasField(getName());
230    }
231}