View Javadoc

1   /*
2    * Copyright 2007 Hippo
3    *
4    * Licensed under the Apache License, Version 2.0 (the  "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" 
12   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  package nl.hippo.client.webdav.binding.content;
17  
18  import java.io.IOException;
19  import java.util.HashSet;
20  import java.util.Iterator;
21  
22  import nl.hippo.client.api.content.Property;
23  
24  import org.jibx.runtime.IAliasable;
25  import org.jibx.runtime.IMarshaller;
26  import org.jibx.runtime.IMarshallingContext;
27  import org.jibx.runtime.IUnmarshaller;
28  import org.jibx.runtime.IUnmarshallingContext;
29  import org.jibx.runtime.JiBXException;
30  import org.jibx.runtime.impl.MarshallingContext;
31  import org.jibx.runtime.impl.UnmarshallingContext;
32  
33  /**
34   * Custom Jibx Marshaller/Unmarshaller for binding the DocumentCollectionImpl XML to the HashMap
35   * of properties in DocumentMetadataImpl
36   */
37  public class DocumentMarshaller implements IMarshaller, IUnmarshaller, IAliasable {
38  
39      // Key element names in the DocumentCollectionImpl XML
40      private static final String METADATA_ELEMENT = "documentMetadata";
41      private static final String PROPERTY_ELEMENT = "property";
42  
43      private static final String NAME_ATTRIBUTE = "name";
44      private static final String NAMESPACE_URI_ATTRIBUTE = "namespace-uri";
45      private static final String NAMESPACE_PREFIX_ATTRIBUTE = "namespace-prefix";
46  
47      /**
48       * Copied javadoc from org.jibx.runtime.IUnMarshaller.
49       * <p>
50       * Check if instance present in XML. This method can be called when the
51       * unmarshalling context is positioned at or just before the start of the data
52       * corresponding to an instance of this mapping. It verifies that the expected
53       * data is present.
54       * 
55       * @param ctx
56       *          unmarshalling context
57       * @return <code>true</code> if expected parse data found,
58       *         <code>false</code> if not
59       * @throws JiBXException
60       *           on error in unmarshalling process
61       */
62      public boolean isPresent(IUnmarshallingContext ctx) throws JiBXException {
63          return ctx.isAt(null, METADATA_ELEMENT);
64      }
65  
66      /**
67       * Copied javadoc from org.jibx.runtime.IUnMarshaller.
68       * <p>
69       * Unmarshal instance of handled class. This method call is responsible for
70       * all handling of the unmarshalling of an object from XML text, including
71       * creating the instance of the handled class if an instance is not supplied.
72       * When it is called the unmarshalling context is always positioned at or just
73       * before the start tag corresponding to the start of the class data.
74       * 
75       * @param obj
76       *          object to be unmarshalled (may be <code>null</code>)
77       * @param ictx
78       *          unmarshalling context
79       * @return unmarshalled object (may be <code>null</code>)
80       * @throws JiBXException
81       *           on error in unmarshalling process
82       */
83      public Object unmarshal(Object obj, IUnmarshallingContext ictx) throws JiBXException {
84  
85          // make sure we're at the appropriate start tag
86          UnmarshallingContext ctx = (UnmarshallingContext) ictx;
87          if (!ctx.isAt(null, METADATA_ELEMENT)) {
88              ctx.throwStartTagNameError(null, METADATA_ELEMENT);
89          }
90          // create new hashset if needed
91          HashSet set = (HashSet) obj;
92          if (set == null) {
93              set = new HashSet();
94          }
95  
96          // skip all entries until we reach a 'resourceMetadata' element
97          ctx.parsePastStartTag(null, METADATA_ELEMENT);
98  
99          // get the 'name' attribute values of each 'property' element, and use the property's text content as value,
100         // and put it in the map.
101         while (ctx.isAt(null, PROPERTY_ELEMENT)) {
102             String name = ctx.attributeText(null, NAME_ATTRIBUTE);
103             String namespaceUri = ctx.attributeText(null, NAMESPACE_URI_ATTRIBUTE);
104             String namespacePrefix = ctx.attributeText(null, NAMESPACE_PREFIX_ATTRIBUTE);
105             ctx.next();
106             String value = ctx.parseContentText();
107 
108             Property prop = new Property(namespacePrefix, namespaceUri, name, value);
109             set.add(prop);
110             ctx.parsePastEndTag(null, PROPERTY_ELEMENT);
111         }
112         ctx.parsePastEndTag(null, METADATA_ELEMENT);
113 
114         return new DocumentMetadataImpl(set);
115     }
116 
117     /**
118      * Copied javadoc from org.jibx.runtime.IMarshaller.
119      * <p>
120      * Check if marshaller represents an extension mapping. This is used by the
121      * framework in generated code to verify compatibility of objects being
122      * marshalled using an abstract mapping.
123      * 
124      * @param index
125      *          abstract mapping index to be checked
126      * @return <code>true</code> if this mapping is an extension of the abstract
127      *         mapping, <code>false</code> if not
128      * 
129      */
130     public boolean isExtension(int index) {
131         return false;
132     }
133 
134     /**
135      * Copied javadoc from org.jibx.runtime.IUnMarshaller.
136      * <p>
137      * Marshal instance of handled class. This method call is responsible for all
138      * handling of the marshalling of an object to XML text. It is called at the
139      * point where the start tag for the associated element should be generated.
140      * 
141      * @param obj
142      *          object to be marshalled (may be <code>null</code> if property is
143      *          not optional)
144      * @param ictx
145      *          XML text output context
146      * @throws JiBXException
147      *           on error in marshalling process
148      */
149     public void marshal(Object obj, IMarshallingContext ictx) throws JiBXException {
150 
151         // make sure the parameters are as expected
152         if (!(obj instanceof DocumentMetadataImpl)) {
153             throw new JiBXException("Invalid object type for marshaller");
154         } else if (!(ictx instanceof MarshallingContext)) {
155             throw new JiBXException("Invalid object type for marshaller");
156         } else {
157 
158             // start by generating start tag for container
159             MarshallingContext ctx = (MarshallingContext) ictx;
160             DocumentMetadataImpl documentMetadata = (DocumentMetadataImpl) obj;
161 
162             ctx.startTag(0, METADATA_ELEMENT).closeStartContent();
163 
164             // loop through all entries in hashmap
165             Iterator iter = documentMetadata.getProperties().iterator();
166             while (iter.hasNext()) {
167                 Property prop = (Property) iter.next();
168 
169                 if (prop.getName() != null) {
170                     ctx.startTagAttributes(0, PROPERTY_ELEMENT);
171                     ctx.attribute(0, NAME_ATTRIBUTE, prop.getName());
172 
173                     if (prop.getNamespacePrefix() != null) {
174                         ctx.attribute(0, NAMESPACE_PREFIX_ATTRIBUTE, prop.getNamespacePrefix());
175                     }
176                     if (prop.getNamespaceUri() != null) {
177                         ctx.attribute(0, NAMESPACE_URI_ATTRIBUTE, prop.getNamespaceUri());
178                     }
179 
180                     if (prop.getValue() != null && prop.getValue().length() > 0) {
181                         ctx.closeStartContent();
182                         try {
183                             ctx.writeCData(prop.getValue());
184                         } catch (IOException e) {
185                             throw new JiBXException("Invalid object type for marshaller");
186                         }
187                         ctx.endTag(0, PROPERTY_ELEMENT);
188                     } else {
189                         ctx.closeStartEmpty();
190                     }
191                 }
192             }
193 
194             // finish with end tag for container element
195             ctx.endTag(0, METADATA_ELEMENT);
196         }
197     }
198 }