1 /*
2 * Portions of this software was developed by employees of the National Institute
3 * of Standards and Technology (NIST), an agency of the Federal Government and is
4 * being made available as a public service. Pursuant to title 17 United States
5 * Code Section 105, works of NIST employees are not subject to copyright
6 * protection in the United States. This software may be subject to foreign
7 * copyright. Permission in the United States and in foreign countries, to the
8 * extent that NIST may hold copyright, to use, copy, modify, create derivative
9 * works, and distribute this software and its documentation without fee is hereby
10 * granted on a non-exclusive basis, provided that this notice and disclaimer
11 * of warranty appears in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT
19 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25 */
26
27 package gov.nist.secauto.metaschema.databind.model.info;
28
29 import com.fasterxml.jackson.core.JsonToken;
30
31 import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
32 import gov.nist.secauto.metaschema.databind.io.BindingException;
33 import gov.nist.secauto.metaschema.databind.io.json.IJsonParsingContext;
34 import gov.nist.secauto.metaschema.databind.io.json.IJsonWritingContext;
35 import gov.nist.secauto.metaschema.databind.io.xml.IXmlParsingContext;
36 import gov.nist.secauto.metaschema.databind.io.xml.IXmlWritingContext;
37 import gov.nist.secauto.metaschema.databind.model.IBoundFieldInstance;
38 import gov.nist.secauto.metaschema.databind.model.IBoundNamedModelInstance;
39 import gov.nist.secauto.metaschema.databind.model.IClassBinding;
40
41 import java.io.IOException;
42
43 import javax.xml.namespace.QName;
44 import javax.xml.stream.XMLStreamException;
45 import javax.xml.stream.events.StartElement;
46
47 import edu.umd.cs.findbugs.annotations.NonNull;
48 import edu.umd.cs.findbugs.annotations.Nullable;
49
50 // TODO: get rid of functional interfaces
51 public interface IDataTypeHandler {
52 @NonNull
53 static IDataTypeHandler newDataTypeHandler(
54 @NonNull IBoundNamedModelInstance targetInstance,
55 @NonNull IClassBinding classBinding) {
56 return new ClassDataTypeHandler(targetInstance, classBinding);
57 }
58
59 @NonNull
60 static IDataTypeHandler newDataTypeHandler(
61 @NonNull IClassBinding classBinding) {
62 return new ClassDataTypeHandler(null, classBinding);
63 }
64
65 @NonNull
66 static IDataTypeHandler newDataTypeHandler(
67 @NonNull IBoundFieldInstance property) {
68 return new JavaTypeAdapterDataTypeHandler(property);
69 }
70
71 /**
72 * Get the class binding associated with this handler.
73 *
74 * @return the class binding or {@code null} if the property's item type is not
75 * a bound class
76 */
77 IClassBinding getClassBinding();
78
79 /**
80 * Get the associated {@link IDataTypeAdapter}, if the data type is not a
81 * complex bound object.
82 *
83 * @return the adpater, or {@code null} otherwise
84 */
85 IDataTypeAdapter<?> getJavaTypeAdapter();
86
87 /**
88 * Indicate if the value supported by this handler allows values without an XML
89 * element wrapper.
90 * <p>
91 * Implementations may proxy this request to the JavaTypeAdapter if it is used
92 * or return {@code false} otherwise.
93 *
94 * @return {@code true} if the underlying data type is allowed to be unwrapped,
95 * or {@code false} otherwise
96 */
97 boolean isUnwrappedValueAllowedInXml();
98
99 boolean isJsonKeyRequired();
100
101 /**
102 * Parse and return the set of items from the JSON stream.
103 * <p>
104 * An item is a complete value, which can be a {@link JsonToken#START_OBJECT},
105 * or a value token.
106 *
107 * @param <T>
108 * the Java type of the bound object described by this class
109 * @param parentObject
110 * the parent Java object to use for serialization callbacks, or
111 * {@code null} if there is no parent
112 * @param context
113 * the JSON/YAML parser
114 * @return the Java object representing the set of parsed items
115 * @throws IOException
116 * if an error occurred while parsing
117 */
118 @NonNull
119 <T> T readItem(
120 @Nullable Object parentObject,
121 @NonNull IJsonParsingContext context) throws IOException;
122
123 /**
124 * Parse and return the set of items from the XML stream.
125 *
126 * @param parentObject
127 * the parent Java object to use for serialization callbacks
128 * @param parentName
129 * the name of the parent (containing) element
130 * @param context
131 * the XML writing context
132 * @return the Java object representing the set of parsed items
133 * @throws IOException
134 * if an error occurred while writing
135 * @throws XMLStreamException
136 * if an error occurred while generating the XML
137 */
138 @NonNull
139 Object readItem(
140 @NonNull Object parentObject,
141 @NonNull StartElement parentName,
142 @NonNull IXmlParsingContext context) throws IOException, XMLStreamException;
143
144 /**
145 * Write the provided {@code targetObject} as JSON.
146 *
147 * @param targetObject
148 * the data to write
149 * @param context
150 * the JSON writing context
151 * @throws IOException
152 * if an error occurred while writing
153 */
154 void writeItem(
155 @NonNull Object targetObject,
156 @NonNull IJsonWritingContext context) throws IOException;
157
158 /**
159 * Write the provided value as XML.
160 *
161 * @param value
162 * the item to write
163 * @param currentParentName
164 * the name of the parent (containing) element
165 * @param context
166 * the JSON serializer
167 * @throws IOException
168 * if an error occurred while writing
169 * @throws XMLStreamException
170 * if an error occurred while generating the XML
171 */
172 void writeItem(
173 @NonNull Object value,
174 @NonNull QName currentParentName,
175 @NonNull IXmlWritingContext context) throws IOException, XMLStreamException;
176
177 /**
178 * Build and return a deep copy of the provided item.
179 *
180 * @param item
181 * the item to copy
182 * @param parentInstance
183 * an optional parent object to use for serialization callbacks
184 * @return the new deep copy
185 * @throws BindingException
186 * if an error occurred while analyzing the bound objects
187 */
188 @NonNull
189 Object copyItem(@NonNull Object item, @Nullable Object parentInstance) throws BindingException;
190
191 }