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.Collections;
019import java.util.HashSet;
020import java.util.Map;
021import java.util.Set;
022import java.util.stream.Collectors;
023
024import org.apache.commons.lang3.StringUtils;
025import org.apache.solr.client.solrj.response.schema.SchemaRepresentation;
026
027/**
028 * Represents the field names of a solr schema, mainly used to track existing fields.
029 */
030public class SchemaFields
031{
032    
033    /** The simple field names. */
034    protected Set<String> _fieldNames;
035    
036    /** The dynamic field names. */
037    protected Set<String> _dynFieldNames;
038    
039    /** The copy field ids. */
040    protected Set<CopyFieldId> _copyFieldIds;
041    
042    /** The field type names. */
043    protected Set<String> _fieldTypeNames;
044    
045    /**
046     * Build a SchemaFields object from a {@link SchemaRepresentation}.
047     * @param schemaRepresentation The schema representation.
048     */
049    public SchemaFields(SchemaRepresentation schemaRepresentation)
050    {
051        initFields(schemaRepresentation);
052    }
053    
054    /**
055     * Get the simple field names.
056     * @return The simple field names.
057     */
058    public Set<String> getFieldNames()
059    {
060        return Collections.unmodifiableSet(_fieldNames);
061    }
062    
063    /**
064     * Test if the schema contains the given simple field.
065     * @param name The field name to test.
066     * @return true if the schema contains the given simple field.
067     */
068    public boolean hasField(String name)
069    {
070        return _fieldNames.contains(name);
071    }
072    
073    /**
074     * Add the given field name.
075     * @param name the field name to add.
076     */
077    public void addField(String name)
078    {
079        _fieldNames.add(name);
080    }
081    
082    /**
083     * Get the dynamic field names.
084     * @return The dynamic field names.
085     */
086    public Set<String> getDynamicFieldNames()
087    {
088        return Collections.unmodifiableSet(_dynFieldNames);
089    }
090    
091    /**
092     * Test if the schema contains the given dynamic field.
093     * @param name The dynamic field name to test.
094     * @return true if the schema contains the given dynamic field.
095     */
096    public boolean hasDynamicField(String name)
097    {
098        return _dynFieldNames.contains(name);
099    }
100    
101    /**
102     * Add a dynamic field name.
103     * @param name the dynamic field name to add.
104     */
105    public void addDynamicField(String name)
106    {
107        _dynFieldNames.add(name);
108    }
109    
110    /**
111     * Get the copy field ids.
112     * @return The copy field ids.
113     */
114    public Set<CopyFieldId> getCopyFieldIds()
115    {
116        return Collections.unmodifiableSet(_copyFieldIds);
117    }
118    
119    /**
120     * Test if the schema contains the given copy field.
121     * @param source The copy field source.
122     * @param destination The copy field destination.
123     * @return true if the schema contains the given copy field.
124     */
125    public boolean hasCopyField(String source, String destination)
126    {
127        return _copyFieldIds.contains(new CopyFieldId(source, destination));
128    }
129    
130    /**
131     * Add the given copy field.
132     * @param source The copy field source.
133     * @param destination The copy field destination.
134     */
135    public void addCopyField(String source, String destination)
136    {
137        _copyFieldIds.add(new CopyFieldId(source, destination));
138    }
139    
140    /**
141     * Get the field types.
142     * @return The field types.
143     */
144    public Set<String> getFieldTypeNames()
145    {
146        return Collections.unmodifiableSet(_fieldTypeNames);
147    }
148    
149    /**
150     * Test if the schema contains the given field type.
151     * @param name The field type name to test.
152     * @return true if the schema contains the given field type.
153     */
154    public boolean hasFieldType(String name)
155    {
156        return _fieldTypeNames.contains(name);
157    }
158    
159    /**
160     * Add the given field type name.
161     * @param name the field type name to add.
162     */
163    public void addFieldType(String name)
164    {
165        _fieldTypeNames.add(name);
166    }
167    
168    @Override
169    public String toString()
170    {
171        StringBuilder str = new StringBuilder();
172        
173        str.append("types=[").append(StringUtils.join(_fieldTypeNames, ", ")).append("]\n")
174           .append("fields=[").append(StringUtils.join(_fieldNames, ", ")).append("]\n")
175           .append("dynamic fields=[").append(StringUtils.join(_dynFieldNames, ", ")).append("]\n")
176           .append("copy fields=[").append(StringUtils.join(_copyFieldIds, ", ")).append("]\n");
177        
178        return str.toString();
179    }
180    
181    /**
182     * Initialize the field names from the schema representation.
183     * @param schema The schema representation.
184     */
185    protected void initFields(SchemaRepresentation schema)
186    {
187        _fieldTypeNames = schema.getFieldTypes().stream().map(type -> (String) type.getAttributes().get("name")).collect(Collectors.toSet());
188        _fieldNames = schema.getFields().stream().map(field -> (String) field.get("name")).collect(Collectors.toSet());
189        _dynFieldNames = schema.getDynamicFields().stream().map(field -> (String) field.get("name")).collect(Collectors.toSet());
190        _copyFieldIds = new HashSet<>();
191        for (Map<String, Object> copyField : schema.getCopyFields())
192        {
193            String source = (String) copyField.get("source");
194            String destination = (String) copyField.get("dest");
195            _copyFieldIds.add(new CopyFieldId(source, destination));
196        }
197    }
198    
199}