001: package org.enhydra.shark.xpdl;
002:
003: import java.io.File;
004: import java.io.FileInputStream;
005: import java.io.StringReader;
006: import java.util.ArrayList;
007: import java.util.Collection;
008: import java.util.HashSet;
009: import java.util.Iterator;
010: import java.util.List;
011: import java.util.Locale;
012: import java.util.Map;
013: import java.util.Set;
014:
015: import org.apache.xerces.parsers.DOMParser;
016: import org.enhydra.shark.utilities.SequencedHashMap;
017: import org.enhydra.shark.xpdl.elements.ExternalPackage;
018: import org.enhydra.shark.xpdl.elements.Package;
019: import org.w3c.dom.Document;
020: import org.xml.sax.InputSource;
021:
022: /**
023: * Implementation of XMLInterface that works with JDK1.3.
024: *
025: * @author Sasa Bojanic
026: */
027: public class XMLInterfaceForJDK13 implements XMLInterface {
028:
029: protected Map idToPackages = new SequencedHashMap();
030: protected Map xmlFileToPackage = new SequencedHashMap();
031: protected Map packageToParentDirectory = new SequencedHashMap();
032:
033: protected String mainPackageReference;
034:
035: protected Map parsingErrorMessages = new SequencedHashMap();
036: protected boolean isValidationON = true;
037:
038: protected XPDLRepositoryHandler xpdlRep = null;
039:
040: protected Locale locale = Locale.getDefault();
041:
042: public void setValidation(boolean isActive) {
043: isValidationON = isActive;
044: }
045:
046: public void clearParserErrorMessages() {
047: parsingErrorMessages.clear();
048: }
049:
050: public synchronized boolean isPackageOpened(String pkgId) {
051: return idToPackages.containsKey(pkgId);
052: }
053:
054: public synchronized Package getPackageById(String pkgId) {
055: ArrayList l = (ArrayList) idToPackages.get(pkgId);
056: Package toRet = null;
057: if (l != null) {
058: Iterator it = l.iterator();
059: int lastVersion = -1;
060: while (it.hasNext()) {
061: Package p = (Package) it.next();
062: String v = p.getInternalVersion();
063: int vi = -1;
064: try {
065: vi = Integer.parseInt(v);
066: } catch (Exception ex) {
067: }
068: if (vi >= lastVersion) {
069: lastVersion = vi;
070: toRet = p;
071: }
072: }
073: if (toRet == null && l.size() > 0) {
074: toRet = (Package) l.get(l.size() - 1);
075: }
076: }
077: return toRet;
078: }
079:
080: public synchronized Package getPackageByIdAndVersion(String pkgId,
081: String version) {
082: ArrayList l = (ArrayList) idToPackages.get(pkgId);
083: Package toRet = null;
084: if (l != null) {
085: Iterator it = l.iterator();
086: while (it.hasNext()) {
087: Package p = (Package) it.next();
088: String v = p.getInternalVersion();
089: if (v.equals(version)) {
090: toRet = p;
091: break;
092: }
093: }
094: }
095: return toRet;
096: }
097:
098: public synchronized Package getPackageByFilename(String filename) {
099: filename = XMLUtil.getCanonicalPath(filename, "", false);
100: return (Package) xmlFileToPackage.get(filename);
101: }
102:
103: public synchronized Package getExternalPackageByRelativeFilePath(
104: String relativePathToExtPkg, Package rootPkg) {
105:
106: File f = new File(relativePathToExtPkg);
107: if (!f.isAbsolute()) {
108: f = new File(getParentDirectory(rootPkg) + File.separator
109: + relativePathToExtPkg);
110: }
111: if (f.exists()) {
112: //System.out.println("Pkg for "+relativePathToExtPkg+"->"+f.getAbsolutePath()+" is found");
113: return getPackageByFilename(f.getAbsolutePath());
114: }
115:
116: //System.out.println("Pkg for "+relativePathToExtPkg+"->"+f.getAbsolutePath()+" is not found");
117: return null;
118: }
119:
120: public synchronized String getAbsoluteFilePath(Package pkg) {
121: Iterator it = xmlFileToPackage.entrySet().iterator();
122: String fullPath = null;
123: while (it.hasNext()) {
124: Map.Entry me = (Map.Entry) it.next();
125: String u = (String) me.getKey();
126: Package p = (Package) me.getValue();
127: if (p.equals(pkg)) {
128: fullPath = u;
129: break;
130: }
131: }
132: return fullPath;
133: }
134:
135: public synchronized Collection getAllPackages() {
136: ArrayList l = new ArrayList();
137: Iterator it = idToPackages.values().iterator();
138: while (it.hasNext()) {
139: l.addAll((ArrayList) it.next());
140: }
141: return l;
142: }
143:
144: public synchronized Collection getAllPackageIds() {
145: return idToPackages.keySet();
146: }
147:
148: public Collection getAllPackageVersions(String pkgId) {
149: ArrayList l = new ArrayList();
150: ArrayList all = (ArrayList) idToPackages.get(pkgId);
151: if (all != null) {
152: Iterator it = all.iterator();
153: while (it.hasNext()) {
154: l.add(((Package) it.next()).getInternalVersion());
155: }
156: }
157: return l;
158: }
159:
160: public synchronized Collection getAllPackageFilenames() {
161: return xmlFileToPackage.keySet();
162: }
163:
164: public synchronized boolean doesPackageFileExists(String xmlFile) {
165: if (new File(xmlFile).exists()) {// || getPackageFileContent(xmlFile)!=null) {
166: return true;
167: }
168:
169: return false;
170: }
171:
172: public synchronized String getParentDirectory(Package pkg) {
173: return (String) packageToParentDirectory.get(pkg);
174: }
175:
176: public Package openPackage(String pkgReference,
177: boolean handleExternalPackages) {
178: //long t1,t2;
179: //t1=System.currentTimeMillis();
180: parsingErrorMessages.clear();
181: mainPackageReference = pkgReference;
182:
183: // this method opens the package. It also opens all of it's external packages
184: // if handleExternalPackages is set to true
185: Package pkg = openPackageRecursively(pkgReference,
186: handleExternalPackages);
187:
188: //printDebug();
189: //t2=System.currentTimeMillis();
190: //System.out.println("OPT="+(t2-t1));
191: return pkg;
192: }
193:
194: public void printDebug() {
195: System.out.println("idToPackage=" + idToPackages);
196: System.out.println("xmlFileToPackage=" + xmlFileToPackage);
197: System.out.println("packageToWorkingDirectory="
198: + packageToParentDirectory);
199: //Package.printDebug();
200: }
201:
202: // Recursive implementation
203: // pkgReference MUST be absolute path
204: protected Package openPackageRecursively(String pkgReference,
205: boolean handleExternalPackages) {
206:
207: Package pkg = null;
208: File f = null;
209: String oldP = pkgReference;
210:
211: String baseDirectory = null;
212: pkgReference = XMLUtil
213: .getCanonicalPath(pkgReference, "", false);
214: if (pkgReference == null) {
215: Set fem = new HashSet();
216: fem.add("File does not exist");
217: parsingErrorMessages.put(oldP, fem);
218: return null;
219: }
220:
221: f = new File(pkgReference);
222: try {
223: baseDirectory = f.getParentFile().getCanonicalPath();
224: } catch (Exception ex) {
225: baseDirectory = f.getParentFile().getAbsolutePath();
226: }
227:
228: if (xmlFileToPackage.containsKey(pkgReference)) {
229: return getPackageByFilename(pkgReference);
230: }
231:
232: pkg = parseDocument(pkgReference, true);
233:
234: if (pkg != null) {
235: String pkgId = pkg.getId();
236: // check if package is already imported
237: if (idToPackages.containsKey(pkgId)) {
238: // check if this is the same package, or just the one with the same id
239: if (xmlFileToPackage.containsKey(pkgReference)) {
240: return getPackageById(pkgId);
241: }
242:
243: throw new RuntimeException(
244: "Can't open two packages with the same Id");
245: }
246: ArrayList l = (ArrayList) idToPackages.get(pkgId);
247: if (l == null) {
248: l = new ArrayList();
249: }
250: l.add(pkg);
251: idToPackages.put(pkgId, l);
252: xmlFileToPackage.put(pkgReference, pkg);
253: try {
254: packageToParentDirectory.put(pkg, f.getParentFile()
255: .getCanonicalPath());
256: } catch (Exception ex) {
257: packageToParentDirectory.put(pkg, f.getParentFile()
258: .getAbsolutePath());
259: }
260:
261: // open all external packages if handleExternalPackages is set to true,
262: // otherwise, it assumes that if there are external packages, the
263: // href element is similar to their Ids
264: Iterator eps = pkg.getExternalPackages().toElements()
265: .iterator();
266: while (eps.hasNext()) {
267: String pathToExtPackage = ((ExternalPackage) eps.next())
268: .getHref();
269: String extPkgId = null;
270: if (handleExternalPackages) {
271: // setting working dir to be the one of the current package
272: String ptep = XMLUtil.getCanonicalPath(
273: pathToExtPackage, baseDirectory, false);
274: //System.setProperty("user.dir",packageToParentDirectory.get(pkg).toString());
275: Package extPkg = openPackageRecursively(ptep,
276: handleExternalPackages);
277: extPkgId = extPkg.getId();
278: } else {
279: extPkgId = XMLUtil
280: .getExternalPackageId(pathToExtPackage);
281: }
282: pkg.addExternalPackageMapping(pathToExtPackage,
283: extPkgId);
284: }
285: } else {
286: System.err.println("Problems with opening file "
287: + pkgReference);
288: }
289: return pkg;
290: }
291:
292: /**
293: * Opens all the packages represented by their streams, and returns first of them.
294: * This implementation assumes that external package references have the similar
295: * name as Id of external package, i.e. if external package reference
296: * is ../tests/maintest/testPackage.xpdl, it is assumed that external package's Id
297: * is testPackage.
298: */
299: public Package openPackagesFromStreams(List pkgContents,
300: boolean isFileStream) throws Exception {
301: Package pkg = null;
302: for (int i = 0; i < pkgContents.size(); i++) {
303: byte[] pkgCont = (byte[]) pkgContents.get(i);
304: Package p = openPackageFromStream(pkgCont, isFileStream);
305: if (i == 0) {
306: pkg = p;
307: }
308: }
309: return pkg;
310: }
311:
312: /**
313: * This implementation assumes that external package references have the similar
314: * name as Id of external package, i.e. if external package reference
315: * is ../tests/maintest/testPackage.xpdl, it is assumed that external package's Id
316: * is testPackage.
317: */
318: public Package openPackageFromStream(byte[] pkgContent,
319: boolean isFileStream) throws Exception {
320: Package pkg = null;
321: if (isFileStream) {
322: String fileContStr = new String(pkgContent, "UTF8");
323: pkg = parseDocument(fileContStr, false);
324: } else {
325: pkg = (Package) XMLUtil.deserialize(pkgContent);
326: }
327: if (pkg != null) {
328: String pkgId = pkg.getId();
329: ArrayList l = (ArrayList) idToPackages.get(pkgId);
330: if (l == null) {
331: l = new ArrayList();
332: }
333: if (!l.contains(pkg)) {
334: l.add(pkg);
335: }
336: idToPackages.put(pkgId, l);
337: Iterator eps = pkg.getExternalPackages().toElements()
338: .iterator();
339: while (eps.hasNext()) {
340: String pathToExtPackage = ((ExternalPackage) eps.next())
341: .getHref();
342: String extPkgId = pkg
343: .getExternalPackageId(pathToExtPackage);
344: if (extPkgId == null) {
345: extPkgId = XMLUtil
346: .getExternalPackageId(pathToExtPackage);
347: pkg.addExternalPackageMapping(pathToExtPackage,
348: extPkgId);
349: }
350: }
351: }
352: return pkg;
353: }
354:
355: public Package parseDocument(String toParse, boolean isFile) {
356: //long t1=0, t2=0, t3=0;
357: //t1=System.currentTimeMillis();
358: Package pkg = null;
359: // Create a Xerces DOM Parser
360: DOMParser parser = new DOMParser();
361:
362: // Parse the Document and traverse the DOM
363: try {
364: parser.setLocale(locale);
365: parser
366: .setFeature(
367: "http://apache.org/xml/features/continue-after-fatal-error",
368: true);
369: ParsingErrors pErrors = new ParsingErrors();
370: parser.setErrorHandler(pErrors);
371: if (isValidationON) {
372: parser.setEntityResolver(new XPDLEntityResolver());
373: parser.setFeature(
374: "http://xml.org/sax/features/validation", true);
375: parser
376: .setFeature(
377: "http://apache.org/xml/features/validation/schema",
378: true);
379: //parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking",true);
380: }
381: if (isFile) {
382: //System.out.println("Parsing from file");
383: //parser.parse(toParse);
384: File f = new File(toParse);
385: if (!f.exists()) {
386: f = new File(f.getCanonicalPath());
387: }
388: parser.parse(new InputSource(new FileInputStream(f))); // Fixed by Harald Meister
389: } else {
390: //System.out.println("Parsing from stream");
391: parser
392: .parse(new InputSource(
393: new StringReader(toParse)));
394: }
395: Document document = parser.getDocument();
396: List errorMessages = pErrors.getErrorMessages();
397: if (errorMessages.size() > 0) {
398: //System.err.println("Errors during document parsing");
399: if (isFile) {
400: parsingErrorMessages.put(toParse, errorMessages);
401: } else {
402: parsingErrorMessages.put("", errorMessages);
403: }
404: }
405: if (document != null) {
406: //pkg=new Package(this);
407: pkg = new Package();
408: //t2=System.currentTimeMillis();
409: getXPDLRepositoryHandler().fromXML(
410: document.getDocumentElement(), pkg);
411: //System.out.println("package "+pkg+" imported");
412: }
413: } catch (Exception ex) {
414: ex.printStackTrace();
415: System.err.println("Fatal error while parsing document");
416: Set fem = new HashSet();
417: fem.add("Fatal error while parsing document:"
418: + ex.getMessage());
419: if (isFile) {
420: parsingErrorMessages.put(toParse, fem);
421: } else {
422: parsingErrorMessages.put("", fem);
423: }
424: return null;
425: }
426: //t3=System.currentTimeMillis();
427: //System.out.println("TOverall ="+(t3-t1));
428: //System.out.println("TParse ="+(t2-t1));
429: //System.out.println("TFXML ="+(t3-t2));
430:
431: return pkg;
432: }
433:
434: /**
435: * This method should be called immediatelly after opening a document,
436: * otherwise, messages could be invalid.
437: * @return The map which keys are opened packages, and values are the sets
438: * of errors for corresponding package.
439: */
440: public Map getParsingErrorMessages() {
441: return parsingErrorMessages;
442: }
443:
444: public synchronized List closePackages(String pkgId) {
445: ArrayList l = (ArrayList) idToPackages.remove(pkgId);
446: if (l != null) {
447: // removing file to package mapping
448: Iterator itr = l.iterator();
449: while (itr.hasNext()) {
450: Package toRemove = (Package) itr.next();
451: Iterator it = xmlFileToPackage.entrySet().iterator();
452: Object keyToRemove = null;
453: while (it.hasNext()) {
454: Map.Entry me = (Map.Entry) it.next();
455: Object key = me.getKey();
456: Object val = me.getValue();
457: if (val.equals(toRemove)) {
458: keyToRemove = key;
459: break;
460: }
461: }
462: if (keyToRemove != null) {
463: xmlFileToPackage.remove(keyToRemove);
464: }
465: packageToParentDirectory.remove(toRemove);
466: }
467: }
468: return l;
469: }
470:
471: public synchronized Package closePackageVersion(String pkgId,
472: String pkgVer) {
473: ArrayList l = (ArrayList) idToPackages.get(pkgId);
474: //System.err.println("CPV1 l="+l);
475: if (l != null && l.size() == 1) {
476: return (Package) this .closePackages(pkgId).get(0);
477: }
478: Package toRemove = null;
479: if (l != null) {
480: // removing file to package mapping
481: Iterator itr = l.iterator();
482: while (itr.hasNext()) {
483: Package p = (Package) itr.next();
484: if (p.getInternalVersion().equals(pkgVer)) {
485: toRemove = p;
486: break;
487: }
488: }
489: //System.err.println("CPV2 toRemove="+toRemove);
490: if (toRemove != null) {
491: Iterator it = xmlFileToPackage.entrySet().iterator();
492: Object keyToRemove = null;
493: while (it.hasNext()) {
494: Map.Entry me = (Map.Entry) it.next();
495: Object key = me.getKey();
496: Object val = me.getValue();
497: if (val.equals(toRemove)) {
498: keyToRemove = key;
499: break;
500: }
501: }
502: if (keyToRemove != null) {
503: xmlFileToPackage.remove(keyToRemove);
504: }
505: packageToParentDirectory.remove(toRemove);
506: l.remove(toRemove);
507: }
508:
509: }
510: return toRemove;
511: }
512:
513: public synchronized void closeAllPackages() {
514: /*System.out.println("I'm XI "+this.hashCode() +" - closing pkgs=");
515: Iterator it=idToPackage.values().iterator();
516: while(it.hasNext()) {
517: Package p=(Package)it.next();
518: System.out.println(" p="+p.getId()+", hc="+p.hashCode());
519: }*/
520: idToPackages.clear();
521: xmlFileToPackage.clear();
522: packageToParentDirectory.clear();
523: }
524:
525: public synchronized void synchronizePackages(
526: XMLInterface xmlInterface) {
527: closeAllPackages();
528:
529: Iterator it = xmlInterface.getAllPackages().iterator();
530: while (it.hasNext()) {
531: Package pkg = (Package) it.next();
532: String pkgId = pkg.getId();
533:
534: ArrayList l = (ArrayList) idToPackages.get(pkgId);
535: if (l == null) {
536: l = new ArrayList();
537: }
538: l.add(pkg);
539: idToPackages.put(pkgId, l);
540: String fp = xmlInterface.getAbsoluteFilePath(pkg);
541: if (fp != null) {
542: xmlFileToPackage.put(fp, pkg);
543: }
544: String pd = xmlInterface.getParentDirectory(pkg);
545: if (pd != null) {
546: packageToParentDirectory.put(pkg, pd);
547: }
548: }
549: }
550:
551: public XPDLRepositoryHandler getXPDLRepositoryHandler() {
552: if (xpdlRep == null) {
553: xpdlRep = new XPDLRepositoryHandler();
554: }
555:
556: return xpdlRep;
557: }
558:
559: public void setXPDLRepositoryHandler(
560: XPDLRepositoryHandler newXPDLRep) {
561: xpdlRep = newXPDLRep;
562: }
563:
564: public void setLocale(Locale locale) {
565: this.locale = locale;
566: }
567: }
|