View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  
23  package org.opencastproject.elasticsearch.impl;
24  
25  import org.opencastproject.elasticsearch.api.Language;
26  import org.opencastproject.elasticsearch.api.SearchMetadata;
27  
28  import java.text.MessageFormat;
29  import java.util.ArrayList;
30  import java.util.Collection;
31  import java.util.HashMap;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  
36  /**
37   * Wrapper that facilitates in posting business objects to the search index.
38   * <p>
39   * This implementation provides utility methods that will ease handling of objects such as dates or users and help
40   * prevent posting of <code>null</code> values.
41   */
42  public class SearchMetadataCollection implements Collection<SearchMetadata<?>> {
43  
44    /** The metadata */
45    protected Map<String, SearchMetadata<?>> metadata = new HashMap<>();
46  
47    /** Returns the document identifier */
48    protected String identifier = null;
49  
50    /** Returns the document type */
51    protected String documentType = null;
52  
53    /**
54     * Creates a new resource metadata collection for the given document type.
55     * <p>
56     * Make sure to set the identifier after the fact using {@link #setIdentifier(String)}.
57     *
58     * @param documentType
59     *          the document type
60     */
61    public SearchMetadataCollection(String documentType) {
62      this(null, documentType);
63    }
64  
65    /**
66     * Creates a new resource metadata collection for the given document type.
67     *
68     * @param identifier
69     *          the document identifier
70     * @param documentType
71     *          the document type
72     */
73    public SearchMetadataCollection(String identifier, String documentType) {
74      this.identifier = identifier;
75      this.documentType = documentType;
76    }
77  
78    /**
79     * Sets the document identifier.
80     *
81     * @param identifier
82     *          the identifier
83     */
84    public void setIdentifier(String identifier) {
85      this.identifier = identifier;
86    }
87  
88    /**
89     * Returns the document identifier.
90     *
91     * @return the identifier
92     */
93    public String getIdentifier() {
94      return identifier;
95    }
96  
97    /**
98     * Returns the document type that determines where the document is posted to the index.
99     *
100    * @return the document type
101    */
102   public String getDocumentType() {
103     return documentType;
104   }
105 
106   /**
107    * Adds the field and its value to the search index.
108    *
109    * @param fieldName
110    *          the field name
111    * @param fieldValue
112    *          the value
113    * @param addToText
114    *          <code>true</code> to add the contents to the fulltext field as well
115    */
116   @SuppressWarnings("unchecked")
117   public void addField(String fieldName, Object fieldValue, boolean addToText) {
118     if (fieldName == null) {
119       throw new IllegalArgumentException("Field name cannot be null");
120     }
121     if (fieldName.contains(".")) {
122       throw new IllegalArgumentException("Field name may not contain '.'");
123     }
124     if (fieldValue == null) {
125       return;
126     }
127 
128     SearchMetadata<Object> m = (SearchMetadata<Object>) metadata.get(fieldName);
129     if (m == null) {
130       m = new SearchMetadataImpl<Object>(fieldName);
131       metadata.put(fieldName, m);
132     }
133 
134     m.setAddToText(addToText);
135 
136     if (fieldValue.getClass().isArray()) {
137       Object[] fieldValues = (Object[]) fieldValue;
138       for (Object v : fieldValues) {
139         m.addValue(v);
140       }
141     } else {
142       m.addValue(fieldValue);
143     }
144   }
145 
146   /**
147    * Returns the localized field name, which is the original field name extended by an underscore and the language
148    * identifier.
149    *
150    * @param fieldName
151    *          the field name
152    * @param language
153    *          the language
154    * @return the localized field name
155    */
156   protected String getLocalizedFieldName(String fieldName, Language language) {
157     return MessageFormat.format(fieldName, language.getIdentifier());
158   }
159 
160   /**
161    * Returns the metadata as a list of {@link SearchMetadata} items.
162    *
163    * @return the metadata items
164    */
165   public List<SearchMetadata<?>> getMetadata() {
166     return new ArrayList<>(metadata.values());
167   }
168 
169   /**
170    * {@inheritDoc}
171    *
172    * @see java.util.Collection#add(java.lang.Object)
173    */
174   public boolean add(SearchMetadata<?> e) {
175     return metadata.put(e.getName(), e) != null;
176   }
177 
178   /**
179    * {@inheritDoc}
180    *
181    * @see java.util.Collection#addAll(java.util.Collection)
182    */
183   public boolean addAll(Collection<? extends SearchMetadata<?>> c) {
184     for (SearchMetadata<?> m : c) {
185       metadata.put(m.getName(), m);
186     }
187     return true;
188   }
189 
190   /**
191    * {@inheritDoc}
192    *
193    * @see java.util.Collection#clear()
194    */
195   public void clear() {
196     metadata.clear();
197   }
198 
199   /**
200    * {@inheritDoc}
201    *
202    * @see java.util.Collection#contains(java.lang.Object)
203    */
204   public boolean contains(Object o) {
205     return metadata.values().contains(o);
206   }
207 
208   /**
209    * {@inheritDoc}
210    *
211    * @see java.util.Collection#containsAll(java.util.Collection)
212    */
213   public boolean containsAll(Collection<?> c) {
214     for (Object o : c) {
215       if (!metadata.values().contains(o)) {
216         return false;
217       }
218     }
219     return true;
220   }
221 
222   /**
223    * {@inheritDoc}
224    *
225    * @see java.util.Collection#isEmpty()
226    */
227   public boolean isEmpty() {
228     return metadata.isEmpty();
229   }
230 
231   /**
232    * {@inheritDoc}
233    *
234    * @see java.util.Collection#iterator()
235    */
236   public Iterator<SearchMetadata<?>> iterator() {
237     List<SearchMetadata<?>> result = new ArrayList<SearchMetadata<?>>();
238     result.addAll(metadata.values());
239     return result.iterator();
240   }
241 
242   /**
243    * {@inheritDoc}
244    *
245    * @see java.util.Collection#remove(java.lang.Object)
246    */
247   public boolean remove(Object o) {
248     return metadata.remove(o) != null;
249   }
250 
251   /**
252    * {@inheritDoc}
253    *
254    * @see java.util.Collection#removeAll(java.util.Collection)
255    */
256   public boolean removeAll(Collection<?> c) {
257     boolean removed = false;
258     for (Object o : c) {
259       removed |= metadata.remove(o) != null;
260     }
261     return removed;
262   }
263 
264   /**
265    * {@inheritDoc}
266    *
267    * @see java.util.Collection#retainAll(java.util.Collection)
268    */
269   public boolean retainAll(Collection<?> c) {
270     boolean removed = false;
271     for (SearchMetadata<?> m : metadata.values()) {
272       if (!c.contains(m)) {
273         metadata.remove(m);
274         removed = true;
275       }
276     }
277     return removed;
278   }
279 
280   /**
281    * {@inheritDoc}
282    *
283    * @see java.util.Collection#size()
284    */
285   public int size() {
286     return metadata.size();
287   }
288 
289   /**
290    * {@inheritDoc}
291    *
292    * @see java.util.Collection#toArray()
293    */
294   public Object[] toArray() {
295     return metadata.values().toArray();
296   }
297 
298   /**
299    * Returns the metadata keys and the metadata items as a map for convenient access of search metadata by key.
300    *
301    * @return the map
302    */
303   public Map<String, SearchMetadata<?>> toMap() {
304     return metadata;
305   }
306 
307   /**
308    * @see java.util.Collection#toArray(java.lang.Object[])
309    */
310   @SuppressWarnings("unchecked")
311   @Override
312   public <T> T[] toArray(T[] arg0) {
313     return (T[]) metadata.values().toArray(new SearchMetadataImpl[metadata.size()]);
314   }
315 
316 }