1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.synchronoss.cpo.meta;
22
23 import org.apache.xmlbeans.*;
24 import org.slf4j.*;
25 import org.synchronoss.cpo.CpoException;
26 import org.synchronoss.cpo.cache.CpoMetaDescriptorCache;
27 import org.synchronoss.cpo.core.cpoCoreMeta.CpoMetaDataDocument;
28 import org.synchronoss.cpo.exporter.*;
29 import org.synchronoss.cpo.helper.*;
30 import org.synchronoss.cpo.meta.domain.*;
31 import org.synchronoss.cpo.parser.ExpressionParser;
32
33 import java.io.*;
34 import java.lang.reflect.*;
35 import java.util.*;
36
37
38
39
40 public class CpoMetaDescriptor extends CpoMetaDescriptorCache implements CpoMetaAdapter, CpoMetaExportable {
41 private static final Logger logger = LoggerFactory.getLogger(CpoMetaDescriptor.class);
42 private String name = null;
43 private boolean caseSensitive = true;
44 private AbstractCpoMetaAdapter metaAdapter = null;
45
46
47 private String defaultPackageName;
48
49 private CpoMetaDescriptor() {
50 }
51
52 protected CpoMetaDescriptor(String name, boolean caseSensitive) throws CpoException {
53 this.name = name;
54 this.caseSensitive = caseSensitive;
55
56
57 try {
58 Class<?> metaAdapterClass = getMetaAdapterClass();
59 logger.debug("Creating MetaAdapter: " + metaAdapterClass.getName());
60 metaAdapter = (AbstractCpoMetaAdapter)metaAdapterClass.newInstance();
61 logger.debug("Created MetaAdapter: " + metaAdapterClass.getName());
62 } catch (InstantiationException ie) {
63 throw new CpoException("Could not instantiate CpoMetaAdapter: " + ExceptionHelper.getLocalizedMessage(ie));
64 } catch (IllegalAccessException iae) {
65 throw new CpoException("Could not access CpoMetaAdapter: " + ExceptionHelper.getLocalizedMessage(iae));
66 } catch (ClassCastException cce) {
67 throw new CpoException("CpoMetaAdapter must extend AbstractCpoMetaAdapter: " + getMetaAdapterClass().getName() + ":" + ExceptionHelper.getLocalizedMessage(cce));
68 }
69 }
70
71 protected Class<?> getMetaAdapterClass() throws CpoException {
72 throw new CpoException("getMetaAdapterClass() must be implemented");
73 }
74
75 public static boolean isValidMetaDescriptor(CpoMetaDescriptor metaDescriptor) {
76 return (findCpoMetaDescriptor(metaDescriptor.getName()) != null);
77 }
78
79 public static CpoMetaDescriptor getInstance(String name) throws CpoException {
80 return findCpoMetaDescriptor(name);
81 }
82
83 public static void removeInstance(String name) throws CpoException {
84 removeCpoMetaDescriptor(name);
85 }
86
87 public static void clearAllInstances() throws CpoException {
88 clearCpoMetaDescriptorCache();
89 }
90
91 public static CpoMetaDescriptor getInstance(String name, String metaXml, boolean caseSensitive) throws CpoException {
92 List<String> metaXmls = new ArrayList<>();
93 metaXmls.add(metaXml);
94 return createUpdateInstance(name, metaXmls, caseSensitive);
95 }
96
97 public static CpoMetaDescriptor getInstance(String name, List<String> metaXmls, boolean caseSensitive) throws CpoException {
98 return createUpdateInstance(name, metaXmls, caseSensitive);
99 }
100
101 public static CpoMetaDescriptor getInstance(String name, String[] metaXmls, boolean caseSensitive) throws CpoException {
102 return createUpdateInstance(name, metaXmls, caseSensitive);
103 }
104
105
106
107
108 public static Collection<String> getCpoMetaDescriptorNames() {
109 return CpoMetaDescriptorCache.getCpoMetaDescriptorNames();
110 }
111
112 public static void refreshDescriptorMeta(String name, List<String> metaXmls) throws CpoException {
113 refreshDescriptorMeta(name,metaXmls, false);
114 }
115
116 public static void refreshDescriptorMeta(String name, List<String> metaXmls, boolean overwrite) throws CpoException {
117 CpoMetaDescriptor metaDescriptor = findCpoMetaDescriptor(name);
118 if (metaDescriptor != null) {
119 metaDescriptor.refreshDescriptorMeta(metaXmls, overwrite);
120 }
121 }
122
123 public void refreshDescriptorMeta(List<String> metaXmls) throws CpoException {
124 refreshDescriptorMeta(metaXmls, false);
125 }
126
127 public void refreshDescriptorMeta(List<String> metaXmls, boolean overwrite) throws CpoException {
128 if (overwrite) {
129 getCpoMetaAdapter().removeAllCpoClass();
130 }
131 createUpdateInstance(this.getName(), metaXmls, caseSensitive);
132 }
133
134 protected static CpoMetaDescriptor createUpdateInstance(String name, List<String> metaXmls, boolean caseSensitive) throws CpoException {
135 return createUpdateInstance(name, metaXmls.toArray(new String[metaXmls.size()]), caseSensitive);
136 }
137
138 protected static CpoMetaDescriptor createUpdateInstance(String name, String[] metaXmls, boolean caseSensitive) throws CpoException {
139 CpoMetaDescriptor metaDescriptor = findCpoMetaDescriptor(name);
140 String metaDescriptorClassName = null;
141
142 for (String metaXml : metaXmls) {
143 InputStream is = CpoClassLoader.getResourceAsStream(metaXml);
144 if (is == null) {
145 logger.info("Resource Not Found: " + metaXml);
146 try {
147 is = new FileInputStream(metaXml);
148 } catch (FileNotFoundException fnfe) {
149 logger.info("File Not Found: " + metaXml);
150 is = null;
151 }
152 }
153 try {
154 CpoMetaDataDocument metaDataDoc;
155 if (is == null) {
156 metaDataDoc = CpoMetaDataDocument.Factory.parse(metaXml);
157 } else {
158 metaDataDoc = CpoMetaDataDocument.Factory.parse(is);
159 }
160
161 String errMsg = XmlBeansHelper.validateXml(metaDataDoc);
162 if (errMsg != null) {
163 throw new CpoException("Invalid metaXml: " + metaXml + ":" + errMsg);
164 }
165
166 if (metaDescriptor == null) {
167 logger.debug("Getting descriptor name");
168 metaDescriptorClassName = metaDataDoc.getCpoMetaData().getMetaDescriptor();
169 logger.debug("Getting the Class");
170 Class<?> clazz = CpoClassLoader.forName(metaDescriptorClassName);
171 logger.debug("Getting the Constructor");
172 if (clazz == null) {
173 logger.debug("clazz==null");
174 }
175 Constructor<?> cons = clazz.getConstructor(String.class, boolean.class);
176 logger.debug("Creating the instance");
177 metaDescriptor = (CpoMetaDescriptor)cons.newInstance(name, caseSensitive);
178 logger.debug("Adding the MetaDescriptor");
179 addCpoMetaDescriptor(metaDescriptor);
180 } else if (!metaDescriptor.getClass().getName().equals(metaDataDoc.getCpoMetaData().getMetaDescriptor())) {
181 throw new CpoException("Error processing multiple metaXml files. All files must have the same CpoMetaDescriptor class name.");
182 }
183
184 metaDescriptor.setDefaultPackageName(metaDataDoc.getCpoMetaData().getDefaultPackageName());
185 metaDescriptor.getCpoMetaAdapter().loadCpoMetaDataDocument(metaDataDoc, caseSensitive);
186 } catch (IOException ioe) {
187 throw new CpoException("Error processing metaData from InputStream: " + metaXml + ": " + ExceptionHelper.getLocalizedMessage(ioe));
188 } catch (XmlException xe) {
189 throw new CpoException("Error processing metaData from String: " + metaXml + ": " + ExceptionHelper.getLocalizedMessage(xe));
190 } catch (ClassNotFoundException cnfe) {
191 throw new CpoException("CpoMetaAdapter not found: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(cnfe));
192 } catch (IllegalAccessException iae) {
193 throw new CpoException("Could not access CpoMetaAdapter: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(iae));
194 } catch (InstantiationException ie) {
195 throw new CpoException("Could not instantiate CpoMetaAdapter: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(ie));
196 } catch (InvocationTargetException ite) {
197 throw new CpoException("Could not invoke constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(ite));
198 } catch (IllegalArgumentException iae) {
199 throw new CpoException("Illegal Argument to constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(iae));
200 } catch (NoSuchMethodException nsme) {
201 throw new CpoException("Could not find constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(nsme));
202 } catch (SecurityException se) {
203 throw new CpoException("Not allowed to access constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(se));
204 } catch (ClassCastException cce) {
205 throw new CpoException("Class is not instance of CpoMetaDescriptor: " + metaDescriptorClassName + ":" + ExceptionHelper.getLocalizedMessage(cce));
206 } finally {
207 if (is != null) {
208 try {
209 is.close();
210 } catch (Exception e) {
211 if (logger.isTraceEnabled()) {
212 logger.trace(e.getLocalizedMessage());
213 }
214 }
215 }
216 }
217 }
218
219 return metaDescriptor;
220 }
221
222 protected static CpoMetaDescriptor createUpdateInstance(CpoMetaDescriptor metaDescriptor, CpoMetaAdapter metaAdapter) throws CpoException {
223 if (metaDescriptor != null && metaAdapter != null) {
224 addCpoMetaDescriptor(metaDescriptor);
225 }
226 return metaDescriptor;
227 }
228
229 protected AbstractCpoMetaAdapter getCpoMetaAdapter() {
230 return metaAdapter;
231 }
232
233 @Override
234 public <T> CpoClass getMetaClass(T obj) throws CpoException {
235 CpoClass cpoClass = getCpoMetaAdapter().getMetaClass(obj);
236 if (cpoClass != null) {
237 cpoClass.loadRunTimeInfo(this);
238 }
239
240 return cpoClass;
241 }
242
243 @Override
244 public List<CpoClass> getCpoClasses() throws CpoException {
245 return getCpoMetaAdapter().getCpoClasses();
246 }
247
248 public void addCpoClass(CpoClass cpoClass) throws CpoException {
249 getCpoMetaAdapter().addCpoClass(cpoClass);
250 }
251
252 public void removeCpoClass(CpoClass cpoClass) throws CpoException {
253 getCpoMetaAdapter().removeCpoClass(cpoClass);
254 }
255
256 @Override
257 public ExpressionParser getExpressionParser() throws CpoException {
258 return getCpoMetaAdapter().getExpressionParser();
259 }
260
261 @Override
262 public String getDataTypeName(CpoAttribute attribute) throws CpoException {
263 return getCpoMetaAdapter().getDataTypeName(attribute);
264 }
265
266 @Override
267 public Class<?> getDataTypeJavaClass(CpoAttribute attribute) throws CpoException {
268 return getCpoMetaAdapter().getDataTypeJavaClass(attribute);
269 }
270
271 @Override
272 public int getDataTypeInt(String dataTypeName) throws CpoException {
273 return getCpoMetaAdapter().getDataTypeInt(dataTypeName);
274 }
275
276 @Override
277 public DataTypeMapEntry<?> getDataTypeMapEntry(int dataTypeInt) throws CpoException {
278 return getCpoMetaAdapter().getDataTypeMapEntry(dataTypeInt);
279 }
280
281 @Override
282 public List<String> getAllowableDataTypes() throws CpoException {
283 return getCpoMetaAdapter().getAllowableDataTypes();
284 }
285
286 public CpoClass createCpoClass() throws CpoException {
287 return getCpoMetaAdapter().createCpoClass(caseSensitive);
288 }
289
290 public CpoAttribute createCpoAttribute() throws CpoException {
291 return getCpoMetaAdapter().createCpoAttribute();
292 }
293
294 public CpoFunctionGroup createCpoFunctionGroup() throws CpoException {
295 return getCpoMetaAdapter().createCpoFunctionGroup();
296 }
297
298 public CpoFunction createCpoFunction() throws CpoException {
299 return getCpoMetaAdapter().createCpoFunction();
300 }
301
302 public CpoArgument createCpoArgument() throws CpoException {
303 return getCpoMetaAdapter().createCpoArgument();
304 }
305
306 public String getDefaultPackageName() {
307 return defaultPackageName;
308 }
309
310 public void setDefaultPackageName(String packageName) {
311 if (packageName != null) {
312 defaultPackageName = packageName;
313 }
314 }
315
316 public String getName() {
317 return name;
318 }
319
320 protected MetaXmlObjectExporter getMetaXmlObjectExporter() {
321 return new CoreMetaXmlObjectExporter(this);
322 }
323
324 protected final CpoMetaDataDocument export() {
325 MetaXmlObjectExporter metaXmlObjectExporter = getMetaXmlObjectExporter();
326
327
328 List<CpoClass> classList = new ArrayList<>();
329 classList.addAll(getCpoMetaAdapter().getCpoClasses());
330 Collections.sort(classList);
331 for (CpoClass cpoClass : classList) {
332 cpoClass.acceptMetaDFVisitor(metaXmlObjectExporter);
333 }
334 return metaXmlObjectExporter.getCpoMetaDataDocument();
335 }
336
337 public final void export(File file) throws CpoException {
338 try {
339 CpoMetaDataDocument doc = export();
340 doc.save(file, XmlBeansHelper.getXmlOptions());
341 } catch (IOException ex) {
342 throw new CpoException(ex.getMessage(), ex);
343 }
344 }
345
346 public final void export(Writer writer) throws CpoException {
347 try {
348 CpoMetaDataDocument doc = export();
349 doc.save(writer, XmlBeansHelper.getXmlOptions());
350 } catch (IOException ex) {
351 throw new CpoException(ex.getMessage(), ex);
352 }
353 }
354
355 public final void export(OutputStream outputStream) throws CpoException {
356 try {
357 CpoMetaDataDocument doc = export();
358 doc.save(outputStream, XmlBeansHelper.getXmlOptions());
359 } catch (IOException ex) {
360 throw new CpoException(ex.getMessage(), ex);
361 }
362 }
363
364 public boolean isCaseSensitive() {
365 return caseSensitive;
366 }
367 }