[AAI] Fix doc config files
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / introspection / MoxyLoader.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.aai.introspection;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import com.google.common.base.CaseFormat;
26 import com.google.common.collect.ImmutableMap;
27
28 import java.io.*;
29 import java.util.HashSet;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.stream.Collectors;
33
34 import javax.xml.bind.JAXBException;
35 import javax.xml.bind.Unmarshaller;
36 import javax.xml.transform.stream.StreamSource;
37
38 import org.eclipse.persistence.dynamic.DynamicEntity;
39 import org.eclipse.persistence.jaxb.UnmarshallerProperties;
40 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
41 import org.onap.aai.exceptions.AAIException;
42 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
43 import org.onap.aai.introspection.exceptions.AAIUnmarshallingException;
44 import org.onap.aai.logging.ErrorLogHelper;
45 import org.onap.aai.logging.LogFormatTools;
46 import org.onap.aai.nodes.CaseFormatStore;
47 import org.onap.aai.nodes.NodeIngestor;
48 import org.onap.aai.restcore.MediaType;
49 import org.onap.aai.schema.enums.ObjectMetadata;
50 import org.onap.aai.setup.SchemaVersion;
51 import org.onap.aai.workarounds.NamingExceptions;
52
53 public class MoxyLoader extends Loader {
54
55     private static final Logger LOGGER = LoggerFactory.getLogger(MoxyLoader.class);
56
57     private DynamicJAXBContext jaxbContext = null;
58     private Map<String, Introspector> allObjs = null;
59
60     private Map<SchemaVersion, MoxyLoader> moxyLoaderFactory;
61
62     private NodeIngestor nodeIngestor;
63     private CaseFormatStore caseFormatStore;
64
65     private Set<String> namedProps;
66
67     public MoxyLoader(SchemaVersion version, NodeIngestor nodeIngestor) {
68         super(version, ModelType.MOXY);
69         this.nodeIngestor = nodeIngestor;
70         this.caseFormatStore = nodeIngestor.getCaseFormatStore();
71         process(version);
72     }
73
74     public MoxyLoader getMoxyLoader(SchemaVersion v) {
75         return moxyLoaderFactory.get(v);
76
77     }
78
79     /**
80      * {@inheritDoc}
81      * 
82      * @throws AAIUnknownObjectException
83      */
84     @Override
85     public Introspector introspectorFromName(String name) throws AAIUnknownObjectException {
86
87         return IntrospectorFactory.newInstance(ModelType.MOXY, objectFromName(name));
88     }
89
90     private boolean containsUpperCase(String str) {
91
92         for (int i = 0; i < str.length(); i++) {
93             if (Character.isUpperCase(str.charAt(i))) {
94                 return true;
95             }
96         }
97
98         return false;
99     }
100
101     /**
102      * {@inheritDoc}
103      */
104     @Override
105     public Object objectFromName(String name) throws AAIUnknownObjectException {
106
107         if (name == null) {
108             throw new AAIUnknownObjectException("null name passed in");
109         }
110         final String sanitizedName = NamingExceptions.getInstance().getObjectName(name);
111         final String upperCamel;
112
113         // Contains any uppercase, then assume it's upper camel
114         if (containsUpperCase(name)) {
115             upperCamel = sanitizedName;
116         } else {
117             upperCamel = caseFormatStore.fromLowerHyphenToUpperCamel(sanitizedName).orElseGet(() -> {
118                 LOGGER.debug("Unable to find {} in the store for lower hyphen to upper camel", sanitizedName);
119                 return CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, sanitizedName);
120             });
121         }
122
123         try {
124             final DynamicEntity result = jaxbContext.newDynamicEntity(upperCamel);
125
126             if (result == null)
127                 throw new AAIUnknownObjectException("Unrecognized AAI object " + name);
128
129             return result;
130         } catch (IllegalArgumentException e) {
131             // entity does not exist
132             throw new AAIUnknownObjectException("Unrecognized AAI object " + name, e);
133         }
134     }
135
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     protected void process(SchemaVersion version) {
141         /*
142          * We need to have just same JaxbContext for each version
143          */
144         jaxbContext = nodeIngestor.getContextForVersion(version);
145
146     }
147
148     /**
149      * {@inheritDoc}
150      */
151     @Override
152     public Introspector unmarshal(String type, String json, MediaType mediaType) throws AAIUnmarshallingException {
153         try {
154             final Object clazz = objectFromName(type);
155             final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
156
157             if (mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) {
158                 unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
159                 unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
160                 unmarshaller.setProperty(UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
161             }
162
163             final DynamicEntity entity = (DynamicEntity) unmarshaller
164                     .unmarshal(new StreamSource(new StringReader(json)), clazz.getClass()).getValue();
165             return IntrospectorFactory.newInstance(ModelType.MOXY, entity);
166         } catch (JAXBException e) {
167             AAIException ex = new AAIException("AAI_4007", e);
168             ErrorLogHelper.logException(ex);
169             throw new AAIUnmarshallingException("Could not unmarshall: " + e.getMessage(), ex);
170         } catch (AAIUnknownObjectException e) {
171             throw new AAIUnmarshallingException("Could not unmarshall: " + e.getMessage(), e);
172         }
173     }
174
175     @Override
176     public Map<String, Introspector> getAllObjects() {
177         if (this.allObjs != null) {
178             return allObjs;
179         } else {
180             ImmutableMap.Builder<String, Introspector> map = new ImmutableMap.Builder<>();
181             Set<String> objs = objectsInVersion();
182             for (String objName : objs) {
183                 try {
184                     Introspector introspector = this.introspectorFromName(objName);
185                     map.put(introspector.getDbName(), introspector);
186                 } catch (AAIUnknownObjectException e) {
187                     LOGGER.warn("Unexpected AAIUnknownObjectException while running getAllObjects() "
188                             + LogFormatTools.getStackTop(e));
189                 }
190             }
191             allObjs = map.build();
192             return allObjs;
193         }
194     }
195
196     private Set<String> objectsInVersion() {
197         Set<String> result = new HashSet<>();
198
199         try {
200             result = nodeIngestor.getObjectsInVersion(getVersion());
201
202         } catch (Exception e) {
203             LOGGER.warn("Exception while enumerating objects for API version " + getVersion()
204                     + " (returning partial results) " + LogFormatTools.getStackTop(e));
205         }
206
207         return result;
208     }
209
210     @Override
211     public Set<String> getNamedPropNodes() {
212
213         if (namedProps == null) {
214             namedProps = getAllObjects().entrySet().stream()
215                     .filter((entry) -> entry.getValue().getMetadata(ObjectMetadata.NAME_PROPS) != null)
216                     .map(entry -> entry.getKey()).collect(Collectors.toSet());
217         }
218
219         return namedProps;
220     }
221
222     public DynamicJAXBContext getJAXBContext() {
223         return this.jaxbContext;
224     }
225 }