View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.tika.metadata;
18  
19  import java.util.Enumeration;
20  import java.util.HashMap;
21  import java.util.Map;
22  import java.util.Properties;
23  
24  /**
25   * A multi-valued metadata container.
26   */
27  public class Metadata implements CreativeCommons, DublinCore, HttpHeaders,
28          MSOffice, TikaMetadataKeys, TikaMimeKeys {
29  
30      /**
31       * A map of all metadata attributes.
32       */
33      private Map<String, String[]> metadata = null;
34  
35      /**
36       * Constructs a new, empty metadata.
37       */
38      public Metadata() {
39          metadata = new HashMap<String, String[]>();
40      }
41  
42      /**
43       * Returns true if named value is multivalued.
44       * 
45       * @param name
46       *          name of metadata
47       * @return true is named value is multivalued, false if single value or null
48       */
49      public boolean isMultiValued(final String name) {
50          return metadata.get(name) != null && metadata.get(name).length > 1;
51      }
52  
53      /**
54       * Returns an array of the names contained in the metadata.
55       * 
56       * @return Metadata names
57       */
58      public String[] names() {
59          return metadata.keySet().toArray(new String[metadata.keySet().size()]);
60      }
61  
62      /**
63       * Get the value associated to a metadata name. If many values are assiociated
64       * to the specified name, then the first one is returned.
65       * 
66       * @param name
67       *          of the metadata.
68       * @return the value associated to the specified metadata name.
69       */
70      public String get(final String name) {
71          String[] values = metadata.get(name);
72          if (values == null) {
73              return null;
74          } else {
75              return values[0];
76          }
77      }
78  
79      /**
80       * Returns the value (if any) of the identified metadata property.
81       *
82       * @since Apache Tika 0.7
83       * @param property property definition
84       * @return property value, or <code>null</code> if the property is not set
85       */
86      public String get(Property property) {
87          return get(property.getName());
88      }
89  
90      /**
91       * Get the values associated to a metadata name.
92       * 
93       * @param name
94       *          of the metadata.
95       * @return the values associated to a metadata name.
96       */
97      public String[] getValues(final String name) {
98          return _getValues(name);
99      }
100 
101     private String[] _getValues(final String name) {
102         String[] values = metadata.get(name);
103         if (values == null) {
104             values = new String[0];
105         }
106         return values;
107     }
108 
109     /**
110      * Add a metadata name/value mapping. Add the specified value to the list of
111      * values associated to the specified metadata name.
112      * 
113      * @param name
114      *          the metadata name.
115      * @param value
116      *          the metadata value.
117      */
118     public void add(final String name, final String value) {
119         String[] values = metadata.get(name);
120         if (values == null) {
121             set(name, value);
122         } else {
123             String[] newValues = new String[values.length + 1];
124             System.arraycopy(values, 0, newValues, 0, values.length);
125             newValues[newValues.length - 1] = value;
126             metadata.put(name, newValues);
127         }
128     }
129 
130     /**
131      * Copy All key-value pairs from properties.
132      * 
133      * @param properties
134      *          properties to copy from
135      */
136     @SuppressWarnings("unchecked")
137     public void setAll(Properties properties) {
138         Enumeration<String> names =
139             (Enumeration<String>) properties.propertyNames();
140         while (names.hasMoreElements()) {
141             String name = names.nextElement();
142             metadata.put(name, new String[] { properties.getProperty(name) });
143         }
144     }
145 
146     /**
147      * Set metadata name/value. Associate the specified value to the specified
148      * metadata name. If some previous values were associated to this name, they
149      * are removed.
150      * 
151      * @param name
152      *          the metadata name.
153      * @param value
154      *          the metadata value.
155      */
156     public void set(String name, String value) {
157         metadata.put(name, new String[] { value });
158     }
159 
160     /**
161      * Sets the value of the identified metadata property.
162      *
163      * @since Apache Tika 0.7
164      * @param property property definition
165      * @param value    property value
166      */
167     public void set(Property property, String value) {
168         set(property.getName(), value);
169     }
170 
171     /**
172      * Remove a metadata and all its associated values.
173      * 
174      * @param name
175      *          metadata name to remove
176      */
177     public void remove(String name) {
178         metadata.remove(name);
179     }
180 
181     /**
182      * Returns the number of metadata names in this metadata.
183      * 
184      * @return number of metadata names
185      */
186     public int size() {
187         return metadata.size();
188     }
189 
190     public boolean equals(Object o) {
191 
192         if (o == null) {
193             return false;
194         }
195 
196         Metadata other = null;
197         try {
198             other = (Metadata) o;
199         } catch (ClassCastException cce) {
200             return false;
201         }
202 
203         if (other.size() != size()) {
204             return false;
205         }
206 
207         String[] names = names();
208         for (int i = 0; i < names.length; i++) {
209             String[] otherValues = other._getValues(names[i]);
210             String[] thisValues = _getValues(names[i]);
211             if (otherValues.length != thisValues.length) {
212                 return false;
213             }
214             for (int j = 0; j < otherValues.length; j++) {
215                 if (!otherValues[j].equals(thisValues[j])) {
216                     return false;
217                 }
218             }
219         }
220         return true;
221     }
222 
223     public String toString() {
224         StringBuffer buf = new StringBuffer();
225         String[] names = names();
226         for (int i = 0; i < names.length; i++) {
227             String[] values = _getValues(names[i]);
228             for (int j = 0; j < values.length; j++) {
229                 buf.append(names[i]).append("=").append(values[j]).append(" ");
230             }
231         }
232         return buf.toString();
233     }
234 
235 }