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  
18  package org.apache.any23.extractor.microdata;
19  
20  import java.net.MalformedURLException;
21  import java.net.URL;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  
29  /**
30   * This class describes a <b>Microdata <i>itemscope</i></b>.
31   *
32   * @author Michele Mostarda (mostarda@fbk.eu)
33   */
34  public class ItemScope extends Item {
35  
36      /**
37       * Map of properties and multi values.
38       */
39      private final Map<String, List<ItemProp>> properties;
40  
41      /**
42       * <i>itemscope</i> DOM identifier in container document.
43       */
44      private final String id;
45  
46      /**
47       * <i>itemscope</i> references.
48       */
49      private final String[] refs;
50  
51      /**
52       * <i>itemscope</i> type.
53       */
54      private final URL type;
55  
56      /**
57       * <i>itemscope</i> external identifier.
58       */
59      private final String itemId;
60  
61      /**
62       * Constructor.
63       *
64       * @param xpath     location of this <i>itemscope</i> within the container document.
65       * @param itemProps list of properties bound to this <i>itemscope</i>.
66       * @param id        DOM identifier for this <i>itemscope</i>. Can be <code>null<code>.
67       * @param refs      list of item prop references connected to this <i>itemscope</i>. Can be <code>null<code>.
68       * @param type      <i>itemscope</i> type. Can be <code>null<code>.
69       * @param itemId    <i>itemscope</i> id. Can be <code>null<code>.
70       */
71      public ItemScope(String xpath, ItemProp[] itemProps, String id, String[] refs, String type, String itemId) {
72          super(xpath);
73  
74          if (itemProps == null) {
75              throw new NullPointerException("itemProps list cannot be null.");
76          }
77          if (type != null) {
78              try {
79                  this.type = new URL(type);
80              } catch (MalformedURLException murle) {
81                  throw new IllegalArgumentException("Invalid type '" + type + "', must be a valid URL.");
82              }
83          } else {
84              this.type = null;
85          }
86          this.id = id;
87          this.refs = refs;
88          this.itemId = itemId;
89  
90          final Map<String, List<ItemProp>> tmpProperties = new HashMap<String, List<ItemProp>>();
91          for (ItemProp itemProp : itemProps) {
92              final String propName = itemProp.getName();
93              List<ItemProp> propList = tmpProperties.get(propName);
94              if (propList == null) {
95                  propList = new ArrayList<ItemProp>();
96                  tmpProperties.put(propName, propList);
97              }
98              propList.add(itemProp);
99          }
100         final Map<String, List<ItemProp>> properties = new HashMap<String, List<ItemProp>>();
101         for (Map.Entry<String, List<ItemProp>> propertiesEntry : tmpProperties.entrySet()) {
102             properties.put(
103                     propertiesEntry.getKey(),
104                     //Collections.unmodifiableList( propertiesEntry.getValue() )
105                     propertiesEntry.getValue()
106             );
107         }
108         // this.properties = Collections.unmodifiableMap(properties);
109         this.properties = properties;
110     }
111 
112     /**
113      * @return map of declared properties, every property can have more than a value.
114      */
115     public Map<String, List<ItemProp>> getProperties() {
116         return properties;
117     }
118 
119     /**
120      * @return the <i>itemscope</i>
121      */
122     public String getId() {
123         return id;
124     }
125 
126     /**
127      * @return <i>itemscope</i> list of references to <i>itemprop</i>s.
128      */
129     public String[] getRefs() {
130         return refs;
131     }
132 
133     /**
134      * @return <i>itemscope</i> type.
135      */
136     public URL getType() {
137         return type;
138     }
139 
140     /**
141      * @return <i>itemscope</i> public identifier.
142      */
143     public String getItemId() {
144         return itemId;
145     }
146 
147     @Override
148     public String toJSON() {
149         StringBuilder sb = new StringBuilder();
150         int i, j;
151         final Collection<List<ItemProp>> itemPropsList = properties.values();
152         j = 0;
153         for (List<ItemProp> itemProps : itemPropsList) {
154             i = 0;
155             for (ItemProp itemProp : itemProps) {
156                 sb.append(itemProp);
157                 if (i < itemProps.size() - 1) {
158                     sb.append(", ");
159                 }
160                 i++;
161             }
162             if (j < itemPropsList.size() - 1) {
163                 sb.append(", ");
164             }
165             j++;
166         }
167         return String.format(
168                 "{ " +
169                         "\"xpath\" : \"%s\", \"id\" : %s, \"refs\" : %s, \"type\" : %s, \"itemid\" : %s, \"properties\" : [ %s ]" +
170                         " }",
171                 getXpath(),
172                 id == null ? null : "\"" + id + "\"",
173                 refs == null ? null : toJSON(refs),
174                 type == null ? null : "\"" + type + "\"",
175                 itemId == null ? null : "\"" + itemId + "\"",
176                 sb.toString()
177         );
178     }
179 
180     @Override
181     public String toString() {
182         return toJSON();
183     }
184 
185     @Override
186     public int hashCode() {
187             return
188                 (properties == null ? 1 : properties.hashCode()) *
189                 (id == null         ? 1 : id.hashCode()) * 2 *
190                 (refs == null       ? 1 : refs.hashCode()) * 3 *
191                 (type == null       ? 1 : type.hashCode()) * 5 *
192                 (itemId == null     ? 1 : itemId.hashCode());
193 
194     }
195 
196     @Override
197     public boolean equals(Object obj) {
198         if (obj == null) {
199             return false;
200         }
201         if (obj == this) {
202             return true;
203         }
204         if (obj instanceof ItemScope) {
205             final ItemScope other = (ItemScope) obj;
206                 return
207                         super.getXpath().equals(other.getXpath())
208                             &&
209                         (properties == null ? other.properties == null : properties.equals(other.properties))
210                             &&
211                         (id == null ? other.id == null : id.equals(other.id))
212                             &&
213                         (refs == null ? other.refs == null : Arrays.equals(refs, other.refs))
214                             &&
215                         (type == null ? other.type == null : type.equals(other.type))
216                             &&
217                         (itemId == null ? other.itemId == null : itemId.equals(other.itemId));
218         }
219         return false;
220     }
221 
222     protected void acquireProperty(ItemProp itemProp) {
223         List<ItemProp> itemProps = properties.get(itemProp.getName());
224         if (itemProps == null) {
225             itemProps = new ArrayList<ItemProp>();
226             properties.put(itemProp.getName(), itemProps);
227         }
228         if (!itemProps.contains(itemProp)) itemProps.add(itemProp);
229     }
230 
231     protected void disownProperty(ItemProp itemProp) {
232         List<ItemProp> propList = properties.get(itemProp.getName());
233         if (propList != null) propList.remove(itemProp);
234     }
235 
236     private String toJSON(String[] in) {
237         StringBuilder sb = new StringBuilder();
238         sb.append('[');
239         for (int i = 0; i < in.length; i++) {
240             sb.append("\"");
241             sb.append(in[i]);
242             sb.append("\"");
243             if (i < in.length - 1) {
244                 sb.append(", ");
245             }
246         }
247         sb.append(']');
248         return sb.toString();
249     }
250 
251 }