001: package org.enhydra.shark.repositorypersistence;
002:
003: import java.io.File;
004: import java.io.FileFilter;
005: import java.io.FileInputStream;
006: import java.io.FileOutputStream;
007: import java.io.InputStream;
008: import java.io.ObjectInputStream;
009: import java.io.ObjectOutputStream;
010: import java.io.OutputStream;
011: import java.io.Serializable;
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.Collections;
015: import java.util.HashMap;
016: import java.util.HashSet;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.Map;
020: import java.util.Set;
021:
022: import org.enhydra.shark.api.client.wfmc.wapi.WMSessionHandle;
023: import org.enhydra.shark.api.common.SharkConstants;
024: import org.enhydra.shark.api.internal.repositorypersistence.RepositoryException;
025: import org.enhydra.shark.api.internal.repositorypersistence.RepositoryPersistenceManager;
026: import org.enhydra.shark.api.internal.working.CallbackUtilities;
027: import org.enhydra.shark.utilities.MiscUtilities;
028: import org.enhydra.shark.xpdl.XMLUtil;
029:
030: /**
031: * File system implementation of Repository persistence interface.
032: *
033: * @author Sasa Bojanic
034: */
035: public class FileSystemRepositoryPersistenceManager implements
036: RepositoryPersistenceManager {
037:
038: private CallbackUtilities cus;
039:
040: // The locations to various repositories
041: private String XPDL_REPOSITORY;
042:
043: // Changed from private to public
044: private String XPDL_HISTORY_REPOSITORY;
045:
046: private final String EXT_REF_FNAME = "#ext_references#";
047:
048: private final String NEXT_IDS_FNAME = "#next_ids#";
049:
050: private final String SER_PKG = "#ser_pkg#";
051:
052: private final String HASH = "#";
053:
054: private String EXT_REFERENCES_FILE_NAME;
055:
056: private String NEXT_IDS_FILE_NAME;
057:
058: private ExternalReferences extRefs;
059:
060: private NextVersions nextVersions;
061:
062: public void configure(CallbackUtilities cus) throws Exception {
063: this .cus = cus;
064: String xr = cus
065: .getProperty("FileSystemRepositoryPersistenceManager.XPDL_REPOSITORY");
066: String hxr = cus
067: .getProperty("FileSystemRepositoryPersistenceManager.XPDL_HISTORY_REPOSITORY");
068: XPDL_REPOSITORY = getRepositoryFullPath(xr);
069: XPDL_HISTORY_REPOSITORY = getRepositoryFullPath(hxr);
070: EXT_REFERENCES_FILE_NAME = XPDL_REPOSITORY + File.separator
071: + EXT_REF_FNAME;
072: NEXT_IDS_FILE_NAME = XPDL_REPOSITORY + File.separator
073: + NEXT_IDS_FNAME;
074:
075: File xrf = new File(XPDL_REPOSITORY);
076: if (!xrf.exists()) {
077: xrf.mkdir();
078: }
079: File hxrf = new File(XPDL_HISTORY_REPOSITORY);
080: if (!hxrf.exists()) {
081: hxrf.mkdir();
082: }
083:
084: File extR = new File(EXT_REFERENCES_FILE_NAME);
085: if (extR.exists()) {
086: extRefs = (ExternalReferences) readFile(EXT_REFERENCES_FILE_NAME);
087: } else {
088: extRefs = new ExternalReferences();
089: }
090:
091: File nextV = new File(NEXT_IDS_FILE_NAME);
092: if (nextV.exists()) {
093: nextVersions = (NextVersions) readFile(NEXT_IDS_FILE_NAME);
094: } else {
095: nextVersions = new NextVersions();
096: }
097: }
098:
099: public void uploadXPDL(WMSessionHandle shandle, String xpdlId,
100: byte[] xpdl, byte[] serializedPkg, long xpdlClassVer)
101: throws RepositoryException {
102: try {
103: String newVersion = nextVersions.updateNextVersion(xpdlId);
104: writeFile(nextVersions, NEXT_IDS_FILE_NAME);
105: FileOutputStream fos = new FileOutputStream(XPDL_REPOSITORY
106: + File.separator + xpdlId + "-" + newVersion);
107: fos.write(xpdl);
108: // Write to file
109: fos.flush();
110: fos.close();
111: fos = new FileOutputStream(XPDL_REPOSITORY + File.separator
112: + xpdlId + "-" + SER_PKG + xpdlClassVer + HASH
113: + "-" + newVersion);
114: fos.write(serializedPkg);
115: // Write to file
116: fos.flush();
117: fos.close();
118: } catch (Exception ex) {
119: cus.error(shandle,
120: "FileSystemRepositoryPersistenceManager -> The upload of the file "
121: + xpdlId + " failed");
122: throw new RepositoryException(ex);
123: }
124: }
125:
126: public void updateXPDL(WMSessionHandle shandle, String xpdlId,
127: String xpdlVersion, byte[] xpdl, byte[] serializedPkg,
128: long xpdlClassVer) throws RepositoryException {
129: try {
130: getXPDLFile(xpdlId, xpdlVersion); // this will throw an exception if file
131: // doesn't exist
132: deleteXPDL(shandle, xpdlId, xpdlVersion);
133: FileOutputStream fos = new FileOutputStream(XPDL_REPOSITORY
134: + File.separator + xpdlId + "-" + xpdlVersion);
135: fos.write(xpdl);
136: // Write to file
137: fos.flush();
138: fos.close();
139: fos = new FileOutputStream(XPDL_REPOSITORY + File.separator
140: + xpdlId + "-" + SER_PKG + xpdlClassVer + HASH
141: + "-" + xpdlVersion);
142: fos.write(serializedPkg);
143: // Write to file
144: fos.flush();
145: fos.close();
146: } catch (Exception ex) {
147: cus.error(shandle,
148: "FileSystemRepositoryPersistenceManager -> The update of the file "
149: + xpdlId + "-" + xpdlVersion + " failed");
150: throw new RepositoryException(ex);
151: }
152: }
153:
154: public void deleteXPDL(WMSessionHandle shandle, String xpdlId,
155: String xpdlVersion) throws RepositoryException {
156: try {
157: if (!getXPDLFile(xpdlId, xpdlVersion).delete()) {
158: throw new RepositoryException("File " + xpdlId + "-"
159: + xpdlVersion
160: + " is not deleted from repository");
161: }
162: if (!getSerializedXPDLFile(xpdlId, xpdlVersion).delete()) {
163: throw new RepositoryException(
164: "The serialized pkg File " + xpdlId + "-"
165: + xpdlVersion
166: + " is not deleted from repository");
167: }
168: extRefs.removeReferrencedIds(xpdlId, xpdlVersion);
169: writeFile(extRefs, EXT_REFERENCES_FILE_NAME);
170: } catch (Exception ex) {
171: throw new RepositoryException(ex);
172: }
173: }
174:
175: public void moveToHistory(WMSessionHandle shandle, String xpdlId,
176: String xpdlVersion) throws RepositoryException {
177: try {
178: File f1 = getXPDLFile(xpdlId, xpdlVersion);
179: File f2 = getSerializedXPDLFile(xpdlId, xpdlVersion);
180:
181: String historyFolder = XPDL_HISTORY_REPOSITORY
182: + File.separator + xpdlId;
183: File fhf = new File(historyFolder);
184: if (!fhf.exists()) {
185: fhf.mkdir();
186: }
187:
188: String historyFilename1 = historyFolder + File.separator
189: + f1.getName() + ".xpdl";
190: String historyFilename2 = historyFolder + File.separator
191: + f2.getName();
192: MiscUtilities.copyFile(f1.getCanonicalPath(),
193: historyFilename1);
194: MiscUtilities.copyFile(f2.getCanonicalPath(),
195: historyFilename2);
196:
197: // delete the removed file from internal repository
198: if (!f1.delete() || !f2.delete()) {
199: throw new RepositoryException("File " + xpdlId + "-"
200: + xpdlVersion
201: + " is not deleted from repository");
202: }
203: extRefs.removeReferrencedIds(xpdlId, xpdlVersion);
204: writeFile(extRefs, EXT_REFERENCES_FILE_NAME);
205: } catch (Exception ex) {
206: throw new RepositoryException(ex);
207: }
208:
209: }
210:
211: public void deleteFromHistory(WMSessionHandle shandle,
212: String xpdlId, String xpdlVersion)
213: throws RepositoryException {
214: List xpdlFiles = getXPDLFiles(XPDL_HISTORY_REPOSITORY
215: + File.separator + xpdlId, false, new XPDLIdFilter(
216: xpdlId, xpdlVersion, true, false));
217: if (xpdlFiles.size() > 0) {
218: if (!((File) xpdlFiles.get(0)).delete()) {
219: throw new RepositoryException(
220: "File is not deleted from history repository");
221: }
222: }
223: xpdlFiles = getXPDLFiles(XPDL_HISTORY_REPOSITORY
224: + File.separator + xpdlId, false, new XPDLIdFilter(
225: xpdlId, xpdlVersion, false, true));
226: if (xpdlFiles.size() > 0) {
227: if (!((File) xpdlFiles.get(0)).delete()) {
228: throw new RepositoryException(
229: "File is not deleted from history repository");
230: }
231: }
232:
233: throw new RepositoryException("There is no xpdl with Id="
234: + xpdlId + ", and version " + xpdlVersion
235: + " in the repository");
236: }
237:
238: public void clearRepository(WMSessionHandle shandle)
239: throws RepositoryException {
240: try {
241: List xpdlFiles = getXPDLFiles(XPDL_REPOSITORY, false,
242: new XPDLIdFilter(null, null, false, false));
243: Iterator itXPDL = xpdlFiles.iterator();
244: while (itXPDL.hasNext()) {
245: if (!((File) itXPDL.next()).delete()) {
246: throw new RepositoryException(
247: "Some file is not deleted from repository");
248: }
249: }
250: xpdlFiles = getXPDLFiles(XPDL_REPOSITORY, false,
251: new XPDLIdFilter(null, null, false, true));
252: itXPDL = xpdlFiles.iterator();
253: while (itXPDL.hasNext()) {
254: if (!((File) itXPDL.next()).delete()) {
255: throw new RepositoryException(
256: "Some file is not deleted from repository");
257: }
258: }
259: } catch (Exception ex) {
260: throw new RepositoryException(ex);
261: }
262: }
263:
264: public String getCurrentVersion(WMSessionHandle shandle,
265: String xpdlId) throws RepositoryException {
266: try {
267: return getFileVersion(getXPDLFile(xpdlId, null));
268: } catch (Exception ex) {
269: throw new RepositoryException(ex);
270: }
271: }
272:
273: public String getNextVersion(WMSessionHandle shandle, String xpdlId)
274: throws RepositoryException {
275: try {
276: return nextVersions.getNextVersion(xpdlId);
277: } catch (Exception ex) {
278: throw new RepositoryException(ex);
279: }
280: }
281:
282: public long getSerializedXPDLObjectVersion(WMSessionHandle shandle,
283: String xpdlId, String xpdlVersion)
284: throws RepositoryException {
285: try {
286: return Long
287: .parseLong(getSerializedFileVersion(getSerializedXPDLFile(
288: xpdlId, xpdlVersion)));
289: } catch (Exception ex) {
290: throw new RepositoryException(ex);
291: }
292: }
293:
294: public long getXPDLUploadTime(WMSessionHandle shandle,
295: String xpdlId, String xpdlVersion)
296: throws RepositoryException {
297: try {
298: return getXPDLFile(xpdlId, xpdlVersion).lastModified();
299: } catch (Exception ex) {
300: throw new RepositoryException(ex);
301: }
302: }
303:
304: public byte[] getXPDL(WMSessionHandle shandle, String xpdlId)
305: throws RepositoryException {
306: try {
307: return fileToByteArray(shandle, getXPDLFile(xpdlId, null));
308: } catch (Exception ex) {
309: throw new RepositoryException(ex);
310: }
311: }
312:
313: public byte[] getSerializedXPDLObject(WMSessionHandle shandle,
314: String xpdlId) throws RepositoryException {
315: try {
316: return fileToByteArray(shandle, getSerializedXPDLFile(
317: xpdlId, null));
318: } catch (Exception ex) {
319: throw new RepositoryException(ex);
320: }
321: }
322:
323: public byte[] getXPDL(WMSessionHandle shandle, String xpdlId,
324: String xpdlVersion) throws RepositoryException {
325: try {
326: return fileToByteArray(shandle, getXPDLFile(xpdlId,
327: xpdlVersion));
328: } catch (Exception ex) {
329: throw new RepositoryException(ex);
330: }
331: }
332:
333: public byte[] getSerializedXPDLObject(WMSessionHandle shandle,
334: String xpdlId, String xpdlVersion)
335: throws RepositoryException {
336: try {
337: return fileToByteArray(shandle, getSerializedXPDLFile(
338: xpdlId, xpdlVersion));
339: } catch (Exception ex) {
340: throw new RepositoryException(ex);
341: }
342: }
343:
344: public List getXPDLVersions(WMSessionHandle shandle, String xpdlId)
345: throws RepositoryException {
346: List xpdlFiles = getXPDLFiles(XPDL_REPOSITORY, false,
347: new XPDLIdFilter(xpdlId, null, false, false));
348: if (xpdlFiles.size() == 0) {
349: throw new RepositoryException("There is no xpdl with Id="
350: + xpdlId + " in the repository");
351: }
352: List xpdlVersions = new ArrayList();
353: Iterator itXPDL = xpdlFiles.iterator();
354: while (itXPDL.hasNext()) {
355: File f = (File) itXPDL.next();
356: try {
357: xpdlVersions.add(getFileVersion(f));
358: } catch (Exception ex) {
359: throw new RepositoryException(ex);
360: }
361: }
362: return xpdlVersions;
363: }
364:
365: public boolean doesXPDLExist(WMSessionHandle shandle, String xpdlId)
366: throws RepositoryException {
367: try {
368: getXPDLFile(xpdlId, null);
369: return true;
370: } catch (Exception ex) {
371: return false;
372: }
373: }
374:
375: public boolean doesXPDLExist(WMSessionHandle shandle,
376: String xpdlId, String xpdlVersion)
377: throws RepositoryException {
378: try {
379: getXPDLFile(xpdlId, xpdlVersion);
380: return true;
381: } catch (Exception ex) {
382: return false;
383: }
384: }
385:
386: public List getExistingXPDLIds(WMSessionHandle shandle)
387: throws RepositoryException {
388: List xpdlFiles = getXPDLFiles(XPDL_REPOSITORY, false,
389: new XPDLIdFilter(null, null, false, false));
390: Set ids = new HashSet();
391: Iterator itXPDL = xpdlFiles.iterator();
392: while (itXPDL.hasNext()) {
393: File f = (File) itXPDL.next();
394: String n = f.getName();
395: int li = n.lastIndexOf("-");
396: String fId = n.substring(0, li);
397: ids.add(fId);
398: }
399:
400: return new ArrayList(ids);
401: }
402:
403: public void addXPDLReference(WMSessionHandle shandle,
404: String referredXPDLId, String referringXPDLId,
405: String referringXPDLVersion, int referredXPDLNumber)
406: throws RepositoryException {
407: try {
408: extRefs.addExtRef(referredXPDLId, referringXPDLId,
409: referringXPDLVersion, referredXPDLNumber);
410: writeFile(extRefs, EXT_REFERENCES_FILE_NAME);
411: } catch (Exception ex) {
412: extRefs.remExtRef(referredXPDLId, referringXPDLId,
413: referringXPDLVersion);
414: throw new RepositoryException(ex);
415: }
416: }
417:
418: public List getReferringXPDLIds(WMSessionHandle shandle,
419: String referredXPDLId) throws RepositoryException {
420: return extRefs.getExtRefIds(referredXPDLId);
421: }
422:
423: public List getReferringXPDLVersions(WMSessionHandle shandle,
424: String referredXPDLId, String refferingXPDLId)
425: throws RepositoryException {
426: return extRefs.getExtRefVersions(referredXPDLId,
427: refferingXPDLId);
428: }
429:
430: public List getReferredXPDLIds(WMSessionHandle shandle,
431: String refferingXPDLId, String refferingXPDLVersion)
432: throws RepositoryException {
433: return extRefs.getReferrencedIds(refferingXPDLId,
434: refferingXPDLVersion);
435: }
436:
437: private void writeFile(Object obj, String fName) throws Exception {
438: OutputStream fos = new FileOutputStream(fName);
439: ObjectOutputStream oout = new ObjectOutputStream(fos);
440: oout.writeObject(obj);
441: oout.flush();
442: oout.close();
443: fos.close();
444: }
445:
446: private Object readFile(String fName) throws Exception {
447: InputStream fis = new FileInputStream(fName);
448: ObjectInputStream oin = new ObjectInputStream(fis);
449: Object obj = oin.readObject();
450: oin.close();
451: return obj;
452: }
453:
454: /**
455: * Returns the full path to the repository based on given path. If repository doesn't
456: * exist, the one is created at that location.
457: *
458: * @param path path (maybe relative) of the repository
459: * @return String containing full path to the repository
460: */
461: private String getRepositoryFullPath(String path) {
462: String rdPath = cus
463: .getProperty(SharkConstants.ROOT_DIRECTORY_PATH_PROP);
464: // System.setProperty("user.dir",rdPath);
465: // if repository don't exist, create it
466: File f = new File(path);
467:
468: if (!f.isAbsolute()) {
469: f = new File(XMLUtil.createPath(rdPath, path));
470: // f=f.getAbsoluteFile();
471: }
472:
473: if (!f.exists()) {
474: if (!f.mkdir()) {
475: return path;
476: }
477: }
478:
479: try {
480: return f.getCanonicalPath();
481: } catch (Exception ex) {
482: return f.getAbsolutePath();
483: }
484: }
485:
486: /**
487: * Converts a file specified to the array of bytes.
488: */
489: private byte[] fileToByteArray(WMSessionHandle shandle,
490: File xpdlFile) throws Exception {
491: // TODO: put this method in Utilities, and see about the one in SharkUtilties.
492: byte[] utf8Bytes = null;
493: if (xpdlFile != null) {
494: try {
495: FileInputStream fis = new FileInputStream(xpdlFile);
496: int noOfBytes = fis.available();
497: if (noOfBytes > 0) {
498: utf8Bytes = new byte[noOfBytes];
499: // must do it byte by byte, otherwise sometimes it will be only partially
500: // read
501: int nextB, i = 0;
502: while ((nextB = fis.read()) != -1) {
503: utf8Bytes[i++] = (byte) nextB;
504: }
505: }
506: } catch (Throwable ex) {
507: cus.error(shandle,
508: "FileSystemRepositoryPersistenceManager -> Problems while getting XPDL file "
509: + xpdlFile);
510: throw new Exception(ex.getMessage());
511: }
512: }
513: return utf8Bytes;
514: }
515:
516: private File getXPDLFile(String xpdlId, String xpdlVersion)
517: throws Exception {
518: List xpdlFiles = getXPDLFiles(XPDL_REPOSITORY, false,
519: new XPDLIdFilter(xpdlId, xpdlVersion, false, false));
520: if (xpdlFiles.size() > 0) {
521: return getLastVersionXPDLFile(xpdlFiles);
522: }
523:
524: throw new Exception("There is no xpdl with Id=" + xpdlId
525: + ", and version " + xpdlVersion + " in the repository");
526: }
527:
528: private File getSerializedXPDLFile(String xpdlId, String xpdlVersion)
529: throws Exception {
530: List xpdlFiles = getXPDLFiles(XPDL_REPOSITORY, false,
531: new XPDLIdFilter(xpdlId, xpdlVersion, false, true));
532: if (xpdlFiles.size() > 0) {
533: return getLastVersionXPDLFile(xpdlFiles);
534: }
535:
536: throw new Exception("There is no xpdl with Id=" + xpdlId
537: + ", and version " + xpdlVersion + " in the repository");
538: }
539:
540: private File getLastVersionXPDLFile(List xpdlFiles)
541: throws Exception {
542: File lastFileVersion = null;
543: int maxVer = -1;
544: Iterator itXPDL = xpdlFiles.iterator();
545: while (itXPDL.hasNext()) {
546: File f = (File) itXPDL.next();
547: String fv = getFileVersion(f);
548: int ver = Integer.parseInt(fv);
549: if (ver > maxVer) {
550: maxVer = ver;
551: lastFileVersion = f;
552: }
553: }
554:
555: if (lastFileVersion == null)
556: throw new Exception(
557: "Something is wrong in XPDL repository - can't determine file version");
558:
559: return lastFileVersion;
560: }
561:
562: private String getFileVersion(File f) throws Exception {
563: String n = f.getName();
564: int li = n.lastIndexOf("-");
565: String fv = n.substring(li + 1);
566: return fv;
567: }
568:
569: private String getSerializedFileVersion(File f) throws Exception {
570: String n = f.getName();
571: int li1 = n.indexOf(SER_PKG);
572: int li2 = n.lastIndexOf(HASH);
573: String fv = n.substring(li1 + SER_PKG.length(), li2);
574: return fv;
575: }
576:
577: // TODO: put this method in utilitites, and see about the one in SharkUtilities
578: private List getXPDLFiles(String repository, boolean traverse,
579: FileFilter ff) {
580: File startingFolder = new File(repository);
581: List packageFiles = new ArrayList();
582: if (traverse) {
583: MiscUtilities.traverse(startingFolder, packageFiles, null);
584: } else {
585: packageFiles = Arrays.asList(startingFolder.listFiles(ff));
586: }
587: return packageFiles;
588: }
589:
590: class XPDLIdFilter implements FileFilter {
591: private String xpdlId;
592:
593: private String xpdlVersion;
594:
595: private boolean hasExtension;
596:
597: private boolean retrieveOnlySerialized;
598:
599: public XPDLIdFilter(String xpdlId, String xpdlVersion,
600: boolean hasExtension, boolean retrieveOnlySerialized) {
601: this .xpdlId = xpdlId;
602: this .xpdlVersion = xpdlVersion;
603: this .hasExtension = hasExtension;
604: this .retrieveOnlySerialized = retrieveOnlySerialized;
605: }
606:
607: public boolean accept(File file) {
608:
609: if (file.isDirectory())
610: return false;
611:
612: String fileName = file.getName();
613: boolean isSerFile = fileName.indexOf(SER_PKG) >= 0;
614: boolean accept = ((retrieveOnlySerialized && isSerFile) || (!retrieveOnlySerialized && fileName
615: .indexOf(HASH) < 0));
616: if (!accept)
617: return false;
618: if (xpdlId == null) {
619: return true;
620: }
621: accept = fileName.startsWith(xpdlId);
622: if (xpdlVersion == null) {
623: return accept;
624: }
625: String endsWith = xpdlVersion;
626: if (hasExtension) {
627: endsWith += ".xpdl";
628: }
629: return accept && fileName.endsWith(endsWith);
630: }
631:
632: }
633:
634: }
635:
636: class ExternalReferences extends HashMap implements Serializable {
637:
638: public synchronized void addExtRef(String refTo, String refFromId,
639: String refFromVersion, int refToNumber) {
640: if (!containsKey(refTo)) {
641: put(refTo, new HashSet());
642: }
643: Set s = (Set) get(refTo);
644: addToSet(s, new RefFrom(refFromId, refFromVersion, refToNumber));
645: }
646:
647: public synchronized void remExtRef(String refTo, String refFromId,
648: String refFromVersion) {
649: Set s = (Set) get(refTo);
650: if (s != null) {
651: removeFromSet(s, new RefFrom(refFromId, refFromVersion));
652: }
653: }
654:
655: public List getExtRefIds(String refTo) {
656: Set ret = new HashSet();
657: Set s = (Set) get(refTo);
658: if (s != null) {
659: Iterator it = s.iterator();
660: while (it.hasNext()) {
661: RefFrom rf = (RefFrom) it.next();
662: ret.add(rf.getRefFromId());
663: }
664: }
665: return new ArrayList(ret);
666: }
667:
668: public List getExtRefVersions(String refTo, String refFromId) {
669: List ret = new ArrayList();
670: Set s = (Set) get(refTo);
671: if (s != null) {
672: Iterator it = s.iterator();
673: while (it.hasNext()) {
674: RefFrom rf = (RefFrom) it.next();
675: if (rf.getRefFromId().equals(refFromId)) {
676: ret.add(rf.getRefFromVersion());
677: }
678: }
679: }
680: return ret;
681: }
682:
683: public List getReferrencedIds(String refFromId,
684: String refFromVersion) {
685: List ret = new ArrayList();
686: Iterator it = entrySet().iterator();
687: while (it.hasNext()) {
688: Map.Entry me = (Map.Entry) it.next();
689: String refTo = (String) me.getKey();
690: Set s = (Set) me.getValue();
691: Iterator itS = s.iterator();
692: while (itS.hasNext()) {
693: RefFrom rf = (RefFrom) itS.next();
694:
695: Map temp = new HashMap();
696: if (rf.getRefFromId().equals(refFromId)
697: && rf.getRefFromVersion()
698: .equals(refFromVersion)) {
699: temp.put(new Integer(rf.getRefNo()), refTo);
700: }
701: List tmp = new ArrayList(temp.keySet());
702: // sort by number
703: Collections.sort(tmp);
704: for (int i = 0; i < tmp.size(); i++) {
705: ret.add(temp.get(tmp.get(i)));
706: }
707:
708: }
709: }
710: return ret;
711: }
712:
713: public synchronized void removeReferrencedIds(String refFromId,
714: String refFromVersion) {
715: List ret = getReferrencedIds(refFromId, refFromVersion);
716: Iterator it = ret.iterator();
717: while (it.hasNext()) {
718: String refTo = (String) it.next();
719: Set s = (Set) get(refTo);
720: removeFromSet(s, new RefFrom(refFromId, refFromVersion));
721: if (s.size() == 0) {
722: remove(refTo);
723: }
724: }
725: }
726:
727: private void addToSet(Set s, RefFrom rf) {
728: Iterator it = s.iterator();
729: boolean contains = false;
730: while (it.hasNext()) {
731: RefFrom rfs = (RefFrom) it.next();
732: if (rfs.equals(rf)) {
733: contains = true;
734: break;
735: }
736: }
737: if (!contains) {
738: s.add(rf);
739: }
740: }
741:
742: // we have to do this because set does not properly remove RefFrom (probably
743: // some Java bug or something)
744: private void removeFromSet(Set s, RefFrom rf) {
745: Iterator it = s.iterator();
746: RefFrom toRem = null;
747: while (it.hasNext()) {
748: RefFrom rfs = (RefFrom) it.next();
749: if (rfs.equals(rf)) {
750: toRem = rfs;
751: break;
752: }
753: }
754: s.remove(toRem);
755: }
756: }
757:
758: class RefFrom implements Serializable {
759: private String refFromId;
760:
761: private String refFromVersion;
762:
763: private int refNo = -1;
764:
765: public RefFrom(String refFromId, String refFromVersion, int refNo) {
766: this .refFromId = refFromId;
767: this .refFromVersion = refFromVersion;
768: this .refNo = refNo;
769: }
770:
771: public RefFrom(String refFromId, String refFromVersion) {
772: this .refFromId = refFromId;
773: this .refFromVersion = refFromVersion;
774: }
775:
776: public String getRefFromId() {
777: return refFromId;
778: }
779:
780: public String getRefFromVersion() {
781: return refFromVersion;
782: }
783:
784: public int getRefNo() {
785: return refNo;
786: }
787:
788: public boolean equals(Object obj) {
789: boolean eq = false;
790: if (obj instanceof RefFrom) {
791: RefFrom refFrom = (RefFrom) obj;
792: eq = (refFrom.refFromId.equals(this .refFromId) && refFrom.refFromVersion
793: .equals(this .refFromVersion));
794: }
795: return eq;
796: }
797:
798: public String toString() {
799: return "[referringId=" + refFromId + ",referringVersion="
800: + refFromVersion + ", refNo=" + refNo + "]";
801: }
802:
803: }
804:
805: class NextVersions extends HashMap implements Serializable {
806: private static final String INITIAL_VERSION = "1";
807:
808: public synchronized String getNextVersion(String xpdlId) {
809: if (containsKey(xpdlId)) {
810: return (String) get(xpdlId);
811: }
812: return INITIAL_VERSION;
813: }
814:
815: public synchronized String updateNextVersion(String xpdlId)
816: throws Exception {
817: String curVersion = INITIAL_VERSION;
818: String nextVersion = INITIAL_VERSION;
819:
820: if (containsKey(xpdlId)) {
821: curVersion = (String) get(xpdlId);
822: }
823:
824: int nver = Integer.parseInt(curVersion) + 1;
825: nextVersion = String.valueOf(nver);
826:
827: put(xpdlId, nextVersion);
828:
829: return curVersion;
830: }
831: }
|