9163f29757d39d94431b472bb3f1efdb1e0a35e5
[aai/aai-common.git] / aai-core / src / main / java / org / openecomp / aai / introspection / MoxyLoader.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
4  * ================================================================================
5  * Copyright (C) 2017 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.openecomp.aai.introspection;
22
23 import java.io.IOException;
24 import java.io.StringReader;
25 import java.util.HashSet;
26 import java.util.Map;
27 import java.util.Set;
28
29 import javax.xml.XMLConstants;
30 import javax.xml.bind.JAXBException;
31 import javax.xml.bind.Unmarshaller;
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.transform.stream.StreamSource;
36
37 import org.eclipse.persistence.dynamic.DynamicEntity;
38 import org.eclipse.persistence.jaxb.UnmarshallerProperties;
39 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
40 import org.openecomp.aai.exceptions.AAIException;
41 import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
42 import org.openecomp.aai.introspection.exceptions.AAIUnmarshallingException;
43 import org.openecomp.aai.logging.ErrorLogHelper;
44 import org.openecomp.aai.restcore.MediaType;
45 import org.openecomp.aai.workarounds.NamingExceptions;
46 import org.w3c.dom.Document;
47 import org.w3c.dom.NodeList;
48 import org.xml.sax.SAXException;
49
50 import com.att.eelf.configuration.EELFLogger;
51 import com.att.eelf.configuration.EELFManager;
52 import com.google.common.base.CaseFormat;
53 import com.google.common.collect.ImmutableMap;
54
55 public class MoxyLoader extends Loader {
56
57         private DynamicJAXBContext jaxbContext = null;
58         private EELFLogger LOGGER = EELFManager.getInstance().getLogger(MoxyLoader.class);
59         private Map<String, Introspector> allObjs = null;
60
61         /**
62          * Instantiates a new moxy loader.
63          *
64          * @param version the version
65          * @param llBuilder the ll builder
66          */
67         protected MoxyLoader(Version version) {
68                 super(version, ModelType.MOXY);
69                 process(version);
70         }
71
72         /**
73          * {@inheritDoc}
74          * @throws AAIUnknownObjectException 
75          */
76         @Override
77         public Introspector introspectorFromName(String name) throws AAIUnknownObjectException {
78
79                 return IntrospectorFactory.newInstance(ModelType.MOXY, objectFromName(name));
80         }
81         
82         /**
83          * {@inheritDoc}
84          */
85         @Override
86         public Object objectFromName(String name) throws AAIUnknownObjectException {
87
88                 if (name == null) {
89                         throw new AAIUnknownObjectException("null name passed in");
90                 }
91                 final String sanitizedName = NamingExceptions.getInstance().getObjectName(name);
92                 final String upperCamel;
93
94                 //Contains any uppercase, then assume it's upper camel
95                 if (name.matches(".*[A-Z].*")) {
96                         upperCamel = sanitizedName;
97                 } else {
98                         upperCamel = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, sanitizedName);
99                 }
100                 
101                 try {
102                         final DynamicEntity result = jaxbContext.newDynamicEntity(upperCamel);
103
104                         if (result == null) throw new AAIUnknownObjectException("Unrecognized AAI object " + name);
105
106                         return result;
107                 } catch (IllegalArgumentException e) {
108                         //entity does not exist
109                         throw new AAIUnknownObjectException("Unrecognized AAI object " + name, e);
110                 }
111         }
112
113         /**
114          * {@inheritDoc}
115          */
116         @Override
117         protected void process(Version version) {
118                 ModelInjestor injestor = ModelInjestor.getInstance();
119                 jaxbContext = injestor.getContextForVersion(version);
120                 
121         }
122
123         /**
124          * {@inheritDoc}
125          */
126         @Override
127         public Introspector unmarshal(String type, String json, MediaType mediaType) throws AAIUnmarshallingException {         
128                 try {
129                         final Object clazz = objectFromName(type);
130                         final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
131
132                         if (mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) {
133                                 unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
134                                 unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
135                                 unmarshaller.setProperty(UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
136                         }
137
138                         final DynamicEntity entity = (DynamicEntity) unmarshaller.unmarshal(new StreamSource(new StringReader(json)), clazz.getClass()).getValue();
139                         return IntrospectorFactory.newInstance(ModelType.MOXY, entity);
140                 } catch (JAXBException e) {
141                         AAIException ex = new AAIException("AAI_4007", e);
142                         ErrorLogHelper.logException(ex);
143                         throw new AAIUnmarshallingException("Could not unmarshall: " + e.getMessage(), ex);
144                 } catch (AAIUnknownObjectException e) {
145                         throw new AAIUnmarshallingException("Could not unmarshall: " + e.getMessage(), e);
146                 }
147         }
148         
149         @Override
150         public Map<String, Introspector> getAllObjects() {
151                 if (this.allObjs != null) {
152                         return allObjs;
153                 } else {
154                         ImmutableMap.Builder<String, Introspector> map = new ImmutableMap.Builder<String, Introspector>();
155                         Set<String> objs = objectsInVersion();
156                         for (String objName : objs) {
157                                 try {
158                                         Introspector introspector = this.introspectorFromName(objName);
159                                         map.put(introspector.getDbName(), introspector);
160                                 } catch (AAIUnknownObjectException e) {
161                                         LOGGER.warn("Unexpected AAIUnknownObjectException while running getAllObjects()", e);
162                                 }
163                         }
164                         allObjs = map.build();
165                         return allObjs;
166                 }
167         }
168         
169         private Set<String> objectsInVersion() {
170                 final Set<String> result = new HashSet<>();
171
172                 try {
173                         final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
174                         final String fileName = ModelInjestor.getInstance().getOXMFileName(getVersion());
175
176                         docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
177
178                         final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
179                         final Document doc = docBuilder.parse(fileName);
180                         final NodeList list = doc.getElementsByTagName("java-type");
181
182                         for (int i = 0; i < list.getLength(); i++) {
183                                 result.add(list.item(i).getAttributes().getNamedItem("name").getNodeValue());
184                         }
185                 } catch (ParserConfigurationException | SAXException | IOException e) {
186                         LOGGER.warn("Exception while enumerating objects for API version " + getVersion() + " (returning partial results)", e);
187                 }
188
189                 result.remove("EdgePropNames");
190                 return result;
191         }
192         
193         public DynamicJAXBContext getJAXBContext() {
194                 return this.jaxbContext;
195         }
196
197 }