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
42 private static final Logger logger = LoggerFactory.getLogger(CpoMetaDescriptor.class);
43 private String name = null;
44 private boolean caseSensitive = true;
45 private AbstractCpoMetaAdapter metaAdapter = null;
46
47
48 private String defaultPackageName;
49
50 private CpoMetaDescriptor() {
51 }
52
53 protected CpoMetaDescriptor(String name, boolean caseSensitive) throws CpoException {
54 this.name = name;
55 this.caseSensitive = caseSensitive;
56
57
58 try {
59 Class metaAdapterClass = getMetaAdapterClass();
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<String>();
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 CpoMetaDescriptor metaDescriptor = findCpoMetaDescriptor(name);
114 if (metaDescriptor != null) {
115 metaDescriptor.refreshDescriptorMeta(metaXmls);
116 }
117 }
118
119 public void refreshDescriptorMeta(List<String> metaXmls) throws CpoException {
120 createUpdateInstance(this.getName(), metaXmls, caseSensitive);
121 }
122
123 protected static CpoMetaDescriptor createUpdateInstance(String name, List<String> metaXmls, boolean caseSensitive) throws CpoException {
124 return createUpdateInstance(name, metaXmls.toArray(new String[metaXmls.size()]), caseSensitive);
125 }
126
127 protected static CpoMetaDescriptor createUpdateInstance(String name, String[] metaXmls, boolean caseSensitive) throws CpoException {
128 CpoMetaDescriptor metaDescriptor = findCpoMetaDescriptor(name);
129 String metaDescriptorClassName = null;
130
131 for (String metaXml : metaXmls) {
132 InputStream is = CpoClassLoader.getResourceAsStream(metaXml);
133 if (is == null) {
134 logger.info("Resource Not Found: " + metaXml);
135 try {
136 is = new FileInputStream(metaXml);
137 } catch (FileNotFoundException fnfe) {
138 logger.info("File Not Found: " + metaXml);
139 is = null;
140 }
141 }
142 try {
143 CpoMetaDataDocument metaDataDoc;
144 if (is == null) {
145 metaDataDoc = CpoMetaDataDocument.Factory.parse(metaXml);
146 } else {
147 metaDataDoc = CpoMetaDataDocument.Factory.parse(is);
148 }
149
150 String errMsg = XmlBeansHelper.validateXml(metaDataDoc);
151 if (errMsg != null) {
152 throw new CpoException("Invalid metaXml: " + metaXml + ":" + errMsg);
153 }
154
155 if (metaDescriptor == null) {
156 logger.debug("Getting descriptor name");
157 metaDescriptorClassName = metaDataDoc.getCpoMetaData().getMetaDescriptor();
158 logger.debug("Getting the Class");
159 Class<?> clazz = CpoClassLoader.forName(metaDescriptorClassName);
160 logger.debug("Getting the Constructor");
161 if (clazz == null) {
162 logger.debug("clazz==null");
163 }
164 Constructor<?> cons = clazz.getConstructor(String.class, boolean.class);
165 logger.debug("Creating the instance");
166 metaDescriptor = (CpoMetaDescriptor)cons.newInstance(name, caseSensitive);
167 addCpoMetaDescriptor(metaDescriptor);
168 } else if (!metaDescriptor.getClass().getName().equals(metaDataDoc.getCpoMetaData().getMetaDescriptor())) {
169 throw new CpoException("Error processing multiple metaXml files. All files must have the same CpoMetaDescriptor class name.");
170 }
171
172 metaDescriptor.setDefaultPackageName(metaDataDoc.getCpoMetaData().getDefaultPackageName());
173 metaDescriptor.getCpoMetaAdapter().loadCpoMetaDataDocument(metaDataDoc, caseSensitive);
174 } catch (IOException ioe) {
175 throw new CpoException("Error processing metaData from InputStream: " + metaXml + ": " + ExceptionHelper.getLocalizedMessage(ioe));
176 } catch (XmlException xe) {
177 throw new CpoException("Error processing metaData from String: " + metaXml + ": " + ExceptionHelper.getLocalizedMessage(xe));
178 } catch (ClassNotFoundException cnfe) {
179 throw new CpoException("CpoMetaAdapter not found: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(cnfe));
180 } catch (IllegalAccessException iae) {
181 throw new CpoException("Could not access CpoMetaAdapter: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(iae));
182 } catch (InstantiationException ie) {
183 throw new CpoException("Could not instantiate CpoMetaAdapter: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(ie));
184 } catch (InvocationTargetException ite) {
185 throw new CpoException("Could not invoke constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(ite));
186 } catch (IllegalArgumentException iae) {
187 throw new CpoException("Illegal Argument to constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(iae));
188 } catch (NoSuchMethodException nsme) {
189 throw new CpoException("Could not find constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(nsme));
190 } catch (SecurityException se) {
191 throw new CpoException("Not allowed to access constructor: " + metaDescriptorClassName + ": " + ExceptionHelper.getLocalizedMessage(se));
192 } catch (ClassCastException cce) {
193 throw new CpoException("Class is not instance of CpoMetaDescriptor: " + metaDescriptorClassName + ":" + ExceptionHelper.getLocalizedMessage(cce));
194 } finally {
195 if (is != null) {
196 try {
197 is.close();
198 } catch (Exception e) {
199 if (logger.isTraceEnabled()) {
200 logger.trace(e.getLocalizedMessage());
201 }
202 }
203 }
204 }
205 }
206
207 return metaDescriptor;
208 }
209
210 protected static CpoMetaDescriptor createUpdateInstance(CpoMetaDescriptor metaDescriptor, CpoMetaAdapter metaAdapter) throws CpoException {
211 if (metaDescriptor != null && metaAdapter != null) {
212 addCpoMetaDescriptor(metaDescriptor);
213 }
214 return metaDescriptor;
215 }
216
217 protected AbstractCpoMetaAdapter getCpoMetaAdapter() {
218 return metaAdapter;
219 }
220
221 @Override
222 public <T> CpoClass getMetaClass(T obj) throws CpoException {
223 CpoClass cpoClass = getCpoMetaAdapter().getMetaClass(obj);
224 if (cpoClass != null && cpoClass.getMetaClass() == null) {
225 cpoClass.loadRunTimeInfo(this);
226 }
227
228 return cpoClass;
229 }
230
231 @Override
232 public List<CpoClass> getCpoClasses() throws CpoException {
233 return getCpoMetaAdapter().getCpoClasses();
234 }
235
236 public void addCpoClass(CpoClass cpoClass) throws CpoException {
237 getCpoMetaAdapter().addCpoClass(cpoClass);
238 }
239
240 public void removeCpoClass(CpoClass cpoClass) throws CpoException {
241 getCpoMetaAdapter().removeCpoClass(cpoClass);
242 }
243
244 @Override
245 public ExpressionParser getExpressionParser() throws CpoException {
246 return getCpoMetaAdapter().getExpressionParser();
247 }
248
249 @Override
250 public String getJavaTypeName(CpoAttribute attribute) throws CpoException {
251 return getCpoMetaAdapter().getJavaTypeName(attribute);
252 }
253
254 @Override
255 public Class getJavaTypeClass(CpoAttribute attribute) throws CpoException {
256 return getCpoMetaAdapter().getJavaTypeClass(attribute);
257 }
258
259 @Override
260 public List<String> getAllowableDataTypes() throws CpoException {
261 return getCpoMetaAdapter().getAllowableDataTypes();
262 }
263
264 public CpoClass createCpoClass() throws CpoException {
265 return getCpoMetaAdapter().createCpoClass(caseSensitive);
266 }
267
268 public CpoAttribute createCpoAttribute() throws CpoException {
269 return getCpoMetaAdapter().createCpoAttribute();
270 }
271
272 public CpoFunctionGroup createCpoFunctionGroup() throws CpoException {
273 return getCpoMetaAdapter().createCpoFunctionGroup();
274 }
275
276 public CpoFunction createCpoFunction() throws CpoException {
277 return getCpoMetaAdapter().createCpoFunction();
278 }
279
280 public CpoArgument createCpoArgument() throws CpoException {
281 return getCpoMetaAdapter().createCpoArgument();
282 }
283
284 public String getDefaultPackageName() {
285 return defaultPackageName;
286 }
287
288 public void setDefaultPackageName(String packageName) {
289 if (packageName != null) {
290 defaultPackageName = packageName;
291 }
292 }
293
294 public String getName() {
295 return name;
296 }
297
298 protected MetaXmlObjectExporter getMetaXmlObjectExporter() {
299 return new CoreMetaXmlObjectExporter(this);
300 }
301
302 protected final CpoMetaDataDocument export() {
303 MetaXmlObjectExporter metaXmlObjectExporter = getMetaXmlObjectExporter();
304
305
306 List<CpoClass> classList = new ArrayList<CpoClass>();
307 classList.addAll(getCpoMetaAdapter().getCpoClasses());
308 Collections.sort(classList);
309 for (CpoClass cpoClass : classList) {
310 cpoClass.acceptMetaDFVisitor(metaXmlObjectExporter);
311 }
312 return metaXmlObjectExporter.getCpoMetaDataDocument();
313 }
314
315 public final void export(File file) throws CpoException {
316 try {
317 CpoMetaDataDocument doc = export();
318 doc.save(file, XmlBeansHelper.getXmlOptions());
319 } catch (IOException ex) {
320 throw new CpoException(ex.getMessage(), ex);
321 }
322 }
323
324 public final void export(Writer writer) throws CpoException {
325 try {
326 CpoMetaDataDocument doc = export();
327 doc.save(writer, XmlBeansHelper.getXmlOptions());
328 } catch (IOException ex) {
329 throw new CpoException(ex.getMessage(), ex);
330 }
331 }
332
333 public final void export(OutputStream outputStream) throws CpoException {
334 try {
335 CpoMetaDataDocument doc = export();
336 doc.save(outputStream, XmlBeansHelper.getXmlOptions());
337 } catch (IOException ex) {
338 throw new CpoException(ex.getMessage(), ex);
339 }
340 }
341
342 public boolean isCaseSensitive() {
343 return caseSensitive;
344 }
345 }