1 package com
.interrupt
.spittoon
;
3 import java
.io
.ByteArrayInputStream
;
4 import java
.io
.InputStream
;
5 import java
.io
.UnsupportedEncodingException
;
6 import java
.util
.Iterator
;
8 import java
.util
.Properties
;
10 import java
.util
.StringTokenizer
;
12 import javax
.servlet
.ServletException
;
14 import org
.xmldb
.api
.DatabaseManager
;
15 import org
.xmldb
.api
.base
.Collection
;
16 import org
.xmldb
.api
.base
.Database
;
17 import org
.xmldb
.api
.base
.XMLDBException
;
18 import org
.xmldb
.api
.modules
.CollectionManagementService
;
19 import org
.xmldb
.api
.modules
.XMLResource
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.exist
.EXistException
;
22 import org
.exist
.storage
.BrokerPool
;
23 import org
.exist
.util
.Configuration
;
24 import org
.exist
.util
.DatabaseConfigurationException
;
26 import com
.interrupt
.bob
.base
.Bob
;
27 import com
.interrupt
.bob
.base
.IBob
;
28 import com
.interrupt
.bob
.util
.Util
;
31 public class Spittoon
{
34 private String DRIVER
= "org.exist.xmldb.DatabaseImpl";
35 private Properties props
= new Properties();
36 private Properties mappings
= new Properties();
38 private String rawDbUrl
= null;
39 private String aauthDbUrl
= null;
40 private String groupsDbUrl
= null;
42 private String rootDir
= null;
43 private String uname
= null;
44 private String passwd
= null;
46 private Logger logger
= Logger
.getLogger(Spittoon
.class);
47 private Database databaseAauth
= null;
48 private Database databaseGroups
= null;
50 public String
getAauthDbUrl() { return aauthDbUrl
; }
51 public void setAauthDbUrl(String aauthDbUrl
) { this.aauthDbUrl
= aauthDbUrl
; }
52 public String
getGroupsDbUrl() { return groupsDbUrl
; }
55 public void setGroupsDbUrl(String groupsDbUrl
) {
56 this.groupsDbUrl
= groupsDbUrl
;
59 public void initialise() {
63 //** load spittoon.properties
64 InputStream inStream
= Spittoon
.class.getResourceAsStream("/spittoon.properties");
67 String einitDb
= System
.getProperty("exist.initdb");
68 if(einitDb
== null || einitDb
.trim().length() < 1)
69 einitDb
= props
.getProperty("exist.initdb");
71 String ehome
= System
.getProperty("exist.home");
72 if(ehome
== null || ehome
.trim().length() < 1)
73 ehome
= props
.getProperty("exist.home");
75 String eSaxValidation
= System
.getProperty("org.xml.sax.features.validation");
76 if(eSaxValidation
== null || eSaxValidation
.trim().length() < 1)
77 eSaxValidation
= props
.getProperty("org.xml.sax.features.validation");
79 String eEndorsedDirs
= System
.getProperty("java.endorsed.dirs");
80 if(eEndorsedDirs
== null || eEndorsedDirs
.trim().length() < 1)
81 eEndorsedDirs
= props
.getProperty("java.endorsed.dirs");
84 logger
.debug("exist.initdb["+einitDb
+"] / exist.home["+ehome
+
85 "] / org.xml.sax.features.validation["+eSaxValidation
+"] / java.endorsed.dirs["+eEndorsedDirs
+"]");
87 String db1Config
= props
.getProperty("db-1-config");
88 String db1Id
= props
.getProperty("db-1-id").trim();
89 String db1Port
= props
.getProperty("db-1-port");
91 String db2Config
= props
.getProperty("db-2-config").trim();
92 String db2Id
= props
.getProperty("db-2-id");
93 String db2Port
= props
.getProperty("db-2-port");
94 logger
.debug("Database / config-1["+ db1Config
+"] / id-1["+ db1Id
+"] / port-1["+db1Port
+"]");
95 logger
.debug("Database / config-2["+ db2Config
+"] / id-2["+ db2Id
+"] / port-2["+db2Port
+"]");
99 //** initialize driver
100 Class cl
= Class
.forName(DRIVER
);
102 databaseAauth
= (Database
)cl
.newInstance();
103 databaseAauth
.setProperty("create-database", einitDb
);
104 databaseAauth
.setProperty("configuration", db1Config
);
105 databaseAauth
.setProperty("database-id", db1Id
);
106 DatabaseManager
.registerDatabase(databaseAauth
);
107 logger
.debug("Database registered["+ databaseAauth
.getName() +"]");
109 databaseGroups
= (Database
)cl
.newInstance();
110 databaseGroups
.setProperty("create-database", einitDb
);
111 databaseGroups
.setProperty("configuration", db2Config
);
112 databaseGroups
.setProperty("database-id", db2Id
);
113 DatabaseManager
.registerDatabase(databaseGroups
);
114 logger
.debug("Database registered["+ databaseGroups
.getName() +"]");
117 System
.setProperty("exist.initdb", einitDb
);
118 System
.setProperty("exist.home", ehome
);
119 System
.setProperty("org.xml.sax.features.validation", eSaxValidation
);
120 System
.setProperty("java.endorsed.dirs", eEndorsedDirs
);
122 //** extract the mappings into a separate properties object
126 //** eXist Broker Pool properties; initialize from properties
127 rawDbUrl
= props
.getProperty("db.url");
128 rootDir
= props
.getProperty("root.dir", "root.dir");
129 uname
= props
.getProperty("db.uname");
130 passwd
= props
.getProperty("db.passwd");
132 rawDbUrl
= rawDbUrl
.trim();
133 rootDir
= rootDir
.trim();
134 uname
= uname
.trim();
135 passwd
= passwd
.trim();
137 if(einitDb
.equals("true")) {
138 aauthDbUrl
= rawDbUrl
.replaceFirst("exist", db1Id
);
139 groupsDbUrl
= rawDbUrl
.replaceFirst("exist", db2Id
);
143 aauthDbUrl
= rawDbUrl
.replaceFirst("exist", db1Id
);
144 groupsDbUrl
= rawDbUrl
.replaceFirst("exist", db2Id
);
146 aauthDbUrl
= aauthDbUrl
.replaceFirst("8080", db1Port
);
147 groupsDbUrl
= groupsDbUrl
.replaceFirst("8080", db2Port
);
150 logger
.debug("RawDBURL["+rawDbUrl
+"] / ROOT["+rootDir
+"] / UNAME["+uname
+"] / PASSWD["+passwd
+"]");
151 logger
.debug("Aauth DBURL["+aauthDbUrl
+"] / Groups DBURL["+groupsDbUrl
+"]");
152 logger
.debug("exist.initdb > " + System
.getProperty("exist.initdb"));
154 Configuration configuration1
= new Configuration(db1Config
);
155 Configuration configuration2
= new Configuration(db2Config
);
156 BrokerPool
.configure( 1, 5, configuration1
);
157 BrokerPool
.configure( 1, 5, configuration2
);
159 //** set Bob properties
160 System
.setProperty(Util
.HOME
, props
.getProperty("bob.home"));
161 System
.setProperty(Util
.BASE
, props
.getProperty("bob.base"));
162 System
.setProperty(Util
.GEN
, props
.getProperty("bob.gen"));
163 System
.setProperty(Util
.END
, props
.getProperty("bob.end"));
164 System
.setProperty(Util
.DEF
, props
.getProperty("bob.def"));
167 catch(DatabaseConfigurationException e
) {
170 catch(EXistException e
) {
179 public void setupRoot() throws SpittoonException
{
181 String db1Id
= props
.getProperty("db-1-id");
182 String db2Id
= props
.getProperty("db-2-id");
184 String aauthDbUrl
= rawDbUrl
.replaceAll("exist", db1Id
);
185 String groupsDbUrl
= rawDbUrl
.replaceAll("exist", db2Id
);
187 createCollection(aauthDbUrl
, rootDir
);
188 createCollection(groupsDbUrl
, rootDir
);
191 public void tearDownRoot() throws SpittoonException
{
193 removeCollection(aauthDbUrl
, rootDir
);
194 removeCollection(groupsDbUrl
, rootDir
);
198 DatabaseManager
.deregisterDatabase(databaseAauth
);
199 logger
.debug("De-registered Database ["+ databaseAauth
.getName() +"]");
201 DatabaseManager
.deregisterDatabase(databaseGroups
);
202 logger
.debug("De-registered Database ["+ databaseGroups
.getName() +"]");
209 private Collection
getCollection(String dbdirectory
) throws SpittoonException
{
211 logger
.debug("Retrieving collection for URL["+ dbdirectory
+"]");
212 Collection dbCollection
= null;
215 dbCollection
= DatabaseManager
.getCollection(dbdirectory
, uname
, passwd
);
216 logger
.debug("Retrieved collection["+ dbCollection
.getName() +"]");
218 catch(XMLDBException e
) {
219 throw new SpittoonException(e
);
224 private Collection
createCollection(String dburl
, String dirname
) throws SpittoonException
{
226 Collection dbCollection
= null;
227 Collection col
= null;
230 logger
.debug("createCollection for dburl["+ dburl
+"]");
232 dbCollection
= DatabaseManager
.getCollection(dburl
, uname
, passwd
);
233 CollectionManagementService mgtService
= (CollectionManagementService
)
234 dbCollection
.getService("CollectionManagementService", "1.0");
235 col
= mgtService
.createCollection(dirname
);
236 logger
.debug("Created directory["+ col
.getName() +"]");
238 catch(XMLDBException e
) {
239 throw new SpittoonException(e
);
244 private void removeCollection(String dburl
, String dirname
) throws SpittoonException
{
246 Collection dbCollection
= null;
249 dbCollection
= DatabaseManager
.getCollection(dburl
, uname
, passwd
);
250 CollectionManagementService mgtService
= (CollectionManagementService
)
251 dbCollection
.getService("CollectionManagementService", "1.0");
252 mgtService
.removeCollection(dirname
);
253 logger
.debug("Removed directory["+ dburl
+ dirname
+"]");
255 catch(XMLDBException e
) {
256 throw new SpittoonException(e
);
262 private void extractMappings() {
265 * deal with a path that is not mapped
267 Set keys
= props
.keySet();
268 Iterator kiter
= keys
.iterator();
269 String nextKey
= null;
270 while(kiter
.hasNext()) {
272 nextKey
= (String
)kiter
.next();
273 if(nextKey
.startsWith("mapping")) {
274 mappings
.setProperty(nextKey
, props
.getProperty(nextKey
));
280 public boolean alive() throws SpittoonException
{
286 * generate root collection URL string
288 StringBuffer sbuffer
= new StringBuffer();
289 sbuffer
.append(aauthDbUrl
);
290 if(!aauthDbUrl
.endsWith("/")) {
293 sbuffer
.append(rootDir
);
294 String rootCollection
= sbuffer
.toString();
297 * see if we have the exist 'db' collection
299 Collection dbCollection
= null;
301 dbCollection
= DatabaseManager
.getCollection(aauthDbUrl
, uname
, passwd
);
302 if(dbCollection
== null) {
303 throw new SpittoonException("Cannot find groups 'db' directory");
306 catch(XMLDBException xe
) {
307 throw new SpittoonException(xe
.getMessage(), xe
.getCause());
311 * test to see if the root collection exists
313 Collection currentCollection
= null;
315 currentCollection
= DatabaseManager
.getCollection(rootCollection
, uname
, passwd
);
316 if(currentCollection
== null)
317 throw new SpittoonException("root collection for aauth DB is NULL");
319 catch(XMLDBException xe
) {
320 throw new SpittoonException(xe
.getMessage(), xe
.getCause());
327 * generate root collection URL string
329 StringBuffer sbuffer
= new StringBuffer();
330 sbuffer
.append(groupsDbUrl
);
331 if(!groupsDbUrl
.endsWith("/")) {
334 sbuffer
.append(rootDir
);
335 String rootCollection
= sbuffer
.toString();
339 * see if we have the exist 'db' collection
341 Collection dbCollection
= null;
343 dbCollection
= DatabaseManager
.getCollection(groupsDbUrl
, uname
, passwd
);
344 if(dbCollection
== null) {
345 throw new SpittoonException("Cannot find groups 'db' directory");
348 catch(XMLDBException xe
) {
349 throw new SpittoonException(xe
.getMessage(), xe
.getCause());
353 * test to see if the root collection exists
355 Collection currentCollection
= null;
357 currentCollection
= DatabaseManager
.getCollection(rootCollection
, uname
, passwd
);
358 if(currentCollection
!= null)
361 catch(XMLDBException xe
) {
362 throw new SpittoonException(xe
.getMessage(), xe
.getCause());
370 public void create(String dbUrl
, String xpath
, String xml
) throws SpittoonException
{
373 logger
.debug("Spittoon.create CALLED / dbUrl["+dbUrl
+"] / xpath["+xpath
+"] / xml["+xml
+"]");
375 //** check if xpath is mapped
376 String bareXPath
= stripXPath(xpath
);
377 //if(!verifyXPathMapping(bareXPath)) {
378 // throw new SpittoonException("XPath mapping ["+ bareXPath +"] not registered");
381 //** load IBob from xml
382 IBob loadedBob
= loadBobFromXML(xml
);
383 String tagName
= loadedBob
.getTagName();
384 tagName
= tagName
.trim();
387 //** check if we're saving the right tag
388 String targetTag
= bareXPath
.substring( (bareXPath
.lastIndexOf("/") + 1) );
389 targetTag
= targetTag
.trim();
390 logger
.debug("Comparing tagName["+tagName
+"] to targetTag["+targetTag
+"]");
391 if(!tagName
.equals(targetTag
))
392 throw new SpittoonException("XML supplied does not match the target xpath");
395 //** find collection from xpath
396 Collection collection
= getCollectionForXPath(dbUrl
, bareXPath
);
397 logger
.debug("Retrieved collection["+ collection
+"]");
398 if(collection
== null) {
400 //** generate collection
401 logger
.debug("Collection is NULL / generating collection...");
402 collection
= generateCollectionFromXPath(dbUrl
, xpath
);
403 logger
.debug("Generated collection ["+ collection
+"]");
406 String resourceName
= generateResourceName(loadedBob
);
409 //** check if document exists
410 logger
.debug("Checking if resource["+resourceName
+"] exists in collection["+collection
.getName()+"]");
411 XMLResource document
= (XMLResource
)collection
.getResource(resourceName
);
412 if(document
== null) {
414 document
= (XMLResource
)collection
.createResource(resourceName
, "XMLResource");
415 logger
.debug("Resource does NOT exist / created resource["+document
.getId()+"] in collection["+collection
.getName()+"]");
417 document
.setContent(loadedBob
.toXML(false));
420 logger
.debug("testing 123 - loadedBob.toXML["+loadedBob
.toXML(false)+"]");
421 logger
.debug("Spittoon.create:: Storing document resource > " + document
.getId() + " > content["+document
.getContent()+"]");
422 collection
.storeResource(document
);
424 catch(XMLDBException e
) {
425 throw new SpittoonException(e
);
427 catch(ClassCastException e
) {
428 throw new SpittoonException(e
);
434 public void createR(String dbUrl
, String xpath
, String xml
) throws SpittoonException
{
437 logger
.debug("Spittoon.createR CALLED / dbUrl["+ dbUrl
+"] / xpath["+ xpath
+"] / xml["+ xml
+"]");
439 //** check if xpath is mapped
440 String bareXPath
= stripXPath(xpath
);
441 //if(!verifyXPathMapping(bareXPath)) {
442 // throw new SpittoonException("XPath mapping ["+ bareXPath +"] not registered");
446 //** load IBob from xml
447 IBob loadedBob
= loadBobFromXML(xml
);
448 String tagName
= loadedBob
.getTagName();
449 tagName
= tagName
.trim();
452 //** check if we're saving the right tag
453 String targetTag
= bareXPath
.substring( (bareXPath
.lastIndexOf("/") + 1) );
454 targetTag
= targetTag
.trim();
455 logger
.debug("Comparing tagName["+tagName
+"] to targetTag["+targetTag
+"]");
456 if(!tagName
.equals(targetTag
))
457 throw new SpittoonException("XML supplied does not match the target xpath");
460 this.generateCollectionFromXPath(dbUrl
, xpath
);
462 //** recurse through tree and save
463 List results
= loadedBob
.find(xpath
);
464 IBob targetBob
= null;
465 if(!results
.isEmpty()) { // is the XML the entire block from 'system'
466 targetBob
= (IBob
)results
.get(0);
470 targetBob
= loadedBob
;
471 //String xtraPath = generateCollectionNameR(xpath, bareXPath);
473 //logger.debug("targetBob = loadedBob / xtraPath["+xtraPath+"] / dbUrl["+dbUrl+"]");
476 logger
.debug("Running SaveOrUpdateVisitor on target["+ targetBob
.toXML(false) +"]");
478 SaveOrUpdateVisitor suVisitor
= new SaveOrUpdateVisitor(this);
479 if(!results
.isEmpty()) {
480 suVisitor
.setParentXPath(
482 (xpath
.lastIndexOf("/") + 1) ));
484 suVisitor
.setDbUrl(dbUrl
);
486 targetBob
.acceptFirst(suVisitor
);
491 private Collection
getCollectionForFullXPath(String dbUrl
, String xpath
) {
493 String bareXPath
= stripXPath(xpath
);
494 logger
.debug("getCollectionForFullXPath:: xpath["+xpath
+"] > bareXPath["+bareXPath
+"]");
496 //** generate collection name
497 String colName
= generateCollectionNameR(xpath
, bareXPath
);
498 logger
.debug("getCollectionForFullXPath:: generated collection name["+ colName
+"]");
501 String dbdirectory
= dbUrl
+ rootDir
+"/"+ colName
;
502 Collection collection
= this.getCollection(dbdirectory
); // use full URL
503 logger
.debug("getCollectionForFullXPath:: retrieved collection["+collection
+"]");
507 public IBob
retrieve(String dbUrl
, String xpath
, boolean recurse
) {
511 * check if there's a child document
513 String bareXPath = stripXPath(xpath);
514 logger.debug("retrieve:: xpath["+xpath+"] > bareXPath["+bareXPath+"]");
516 //** generate collection name
517 String colName = generateCollectionNameR(xpath, bareXPath);
518 logger.debug("retrieve:: generated collection name["+ colName +"]");
521 String dbdirectory = dbUrl + rootDir +"/"+ colName;
522 Collection collection = this.getCollection(dbdirectory); // use full URL
526 * check if there's a child document
528 logger
.debug("Retrieving for > dbUrl["+ dbUrl
+"] / xpath["+ xpath
+"]");
529 Collection collection
= getCollectionForFullXPath(dbUrl
, xpath
);
531 //** child resource will be named the same as the directory
532 IBob resultBob
= null;
535 String rname
= collection
.getName();
536 rname
= rname
.substring(rname
.lastIndexOf("/") + 1);
537 XMLResource eachResource
= (XMLResource
)collection
.getResource(rname
);
538 logger
.debug("Child resource ["+ eachResource
+"] > forName["+rname
+"] > inCollection["+collection
.getName()+"]");
540 if(eachResource
== null) {
541 throw new SpittoonException("NULL child resource in directory ["+ collection
.getName()+"]");
545 * if yes, then i) add to parent 'bob' ii) set as parent 'bob'
547 resultBob
= this.loadBobFromXML((String
)eachResource
.getContent());
548 logger
.debug("retrieve:: recurse > found child XML tag["+ resultBob
.getTagName() +"] > ["+ resultBob
.xpath(true) +"]");
550 /*if(parent != null) {
552 FindParentBob fpvisitor = new FindParentBob();
553 fpvisitor.setTagName(resultBob.getTagName());
554 fpvisitor.setAttributeValue(resultBob.getAttributeValue("id"));
555 fpvisitor.setReplacement(resultBob);
556 parent.acceptFirst(fpvisitor); //** i)
558 logger.debug("OK > new parent after replace... " + parent.toXML(false));
563 //** should we recurse
566 //** get child collections
567 String
[] childCollections
= collection
.listChildCollections();
569 for (String string
: childCollections
) {
571 //** for each child collection, recurse to it's children
572 String tname
= string
.substring(0, string
.indexOf("."));
573 String idvalue
= string
.substring(string
.indexOf(".") + 1);
575 StringBuffer sbuf
= new StringBuffer(xpath
);
579 sbuf
.append("@id='");
580 sbuf
.append(idvalue
);
583 //** next XML retrieved
584 String eachXPath
= sbuf
.toString();
585 logger
.debug("retrieve:: recurse > XPath > " + eachXPath
);
587 eachBob
= retrieve(dbUrl
, eachXPath
, recurse
); //** ii)
588 resultBob
.remove(eachBob
.getTagName(), "id", eachBob
.getAttributeValue("id"));
589 resultBob
.addChild(eachBob
);
595 catch(XMLDBException e
) {
596 throw new SpittoonException(e
);
602 public Collection
getCollectionForXPath(String dbUrl
, String bareXPath
) throws SpittoonException
{
605 //if(!verifyXPathMapping(bareXPath)) {
606 // throw new SpittoonException("XPath ["+ bareXPath +"] is not mapped");
609 String eurl
= generateDbUrl((dbUrl
+ rootDir
), bareXPath
);
610 logger
.debug("getCollectionForXPath:: Generated eurl["+ eurl
+"]");
612 Collection collection
= null;
614 collection
= DatabaseManager
.getCollection(eurl
, uname
, passwd
);
616 catch(XMLDBException e
) {
617 throw new SpittoonException(e
.getMessage(), e
);
623 public Collection
generateCollectionFromXPath(String dbUrl
, String xpath
) throws SpittoonException
{
625 logger
.debug("Spittoon.generateCollectionFromXPath:: dbUrl["+ dbUrl
+"] / xpath["+ xpath
+"]");
626 String bareXPath
= stripXPath(xpath
);
628 //if(!verifyXPathMapping(bareXPath)) {
629 // throw new SpittoonException("XPath ["+ bareXPath +"] is not mapped");
632 String baseName
= dbUrl
+ rootDir
;
633 String eurl
= dbUrl
+ rootDir
;
634 logger
.debug("generateCollectionFromXPath:: Generated rootUrl["+ eurl
+"]");
637 StringTokenizer stokenizer
= new StringTokenizer( bareXPath
, "/" );
638 StringTokenizer xpathTokenizer
= new StringTokenizer( xpath
, "/" ); //** mirroring stokenizer in loop ** It's bad, I know, I knooowwww **
639 Collection nextCollection
= null;
642 //** this should be the root collection
643 nextCollection
= DatabaseManager
.getCollection(eurl
, uname
, passwd
);
644 //logger.debug("1. Next collection["+ nextCollection +"]");
645 if(nextCollection
== null)
646 throw new SpittoonException("There is no root collection["+ eurl
+"]");
648 String nextToken
= stokenizer
.nextToken();
649 String nextXPath
= xpathTokenizer
.nextToken();
650 String previousUrl
= null;
652 //logger.debug("1. nextToken ["+ nextToken +"] / nextXPath["+ nextXPath +"]");
654 boolean moreTokens
= false;
655 if(nextToken
!= null)
659 //String checkMappingS = "";
661 while((nextCollection
!= null) && moreTokens
) {
665 logger
.debug("nextToken["+nextToken
+"] / nextXPath["+ nextXPath
+"]");
666 String colName
= generateNextCollectionName(nextToken
, nextXPath
);
667 eurl
+= "/" + colName
;
669 /** check if collection is mapped
670 checkMappingS += "/" + nextToken;
671 logger.debug("generateCollectionFromXPath:: verifying mapping > ["+ verifyXPathMapping(checkMappingS) +"] > ["+ checkMappingS +"]");
673 if(!verifyXPathMapping(checkMappingS)) {
675 //** if xpath is not mapped, do not create a collection
677 //** KLUDGE 1 - some control stuff
678 if(stokenizer.hasMoreTokens()) {
680 nextToken = stokenizer.nextToken();
681 nextXPath = xpathTokenizer.nextToken();
692 logger
.debug("Looking for the next collection["+eurl
+"]");
694 nextCollection
= DatabaseManager
.getCollection(eurl
, uname
, passwd
);
695 if(nextCollection
== null) {
697 logger
.debug(">> didn't find the last collection / eurl["+eurl
+"]... creating previousUrl["+previousUrl
+"] / collection name["+colName
+"]");
698 nextCollection
= createCollection(previousUrl
, colName
);
699 logger
.debug(">> Created the next collection["+ nextCollection
+"] / url["+ previousUrl
+"/"+ colName
+"]");
705 if(stokenizer
.hasMoreTokens()) {
707 nextToken
= stokenizer
.nextToken();
708 nextXPath
= xpathTokenizer
.nextToken();
709 //logger.debug("2. nextToken ["+ nextToken +"]");
716 catch(XMLDBException e
) {
717 throw new SpittoonException(e
.getMessage(), e
);
720 return nextCollection
;
723 private String
generateCollectionNameR(String xpath
, String bareXPath
) {
726 StringTokenizer xtokenizer
= new StringTokenizer(xpath
, "/");
727 StringTokenizer btokenizer
= new StringTokenizer(bareXPath
, "/");
731 String eachPart
= null;
732 StringBuffer sbuffer
= new StringBuffer();
734 while(xtokenizer
.hasMoreTokens()) {
736 eachx
= xtokenizer
.nextToken();
737 eachb
= btokenizer
.nextToken();
739 eachPart
= generateNextCollectionName(eachb
, eachx
);
740 logger
.info("generateCollectionNameR:: eachx["+ eachx
+"] > eachb["+ eachb
+"] > eachPart["+ eachPart
+"]");
742 sbuffer
.append(eachPart
);
743 if(xtokenizer
.hasMoreTokens())
746 String resultName
= sbuffer
.toString();
747 logger
.info("generateCollectionNameR:: result["+ resultName
+"]");
751 private String
generateNextCollectionName(String nextToken
, String nextXPath
) {
753 String yvalue
= yankAttributeId(nextXPath
);
754 logger
.info("generating Collection name / nextXPath ["+ nextXPath
+"] / yanked 'id' value ["+ yvalue
+"] ...");
756 return nextToken
+ "." + yvalue
;
758 private String
yankAttributeId(String attributeString
) {
760 logger
.debug("yankAttributeId["+ attributeString
+"]");
762 //** test yanking 'id' attribute
763 //** make sure there's an 'id' attribute
764 int ii
= attributeString
.indexOf("@id");
768 attributeString
.substring(ii
, jj
);
770 catch(StringIndexOutOfBoundsException e
) {
771 throw new SpittoonException("No 'id' attribute specified for ["+ attributeString
+"]", e
);
774 //** find value for id attribute
775 String marker
= attributeString
.substring(jj
);
776 //logger.info("yanking marker["+marker+"]");
778 int kk
= marker
.indexOf("\"");
783 kk
= marker
.indexOf("'");
784 int ll
= marker
.indexOf("'", kk
+ 1);
785 subs
= marker
.substring(kk
+ 1, ll
);
787 //logger.info("yanking >> ' > kk["+ kk +"] / ll["+ll+"] / marker["+marker+"] / subs["+subs+"]");
792 int ll
= marker
.indexOf("\"", kk
+ 1);
793 subs
= marker
.substring(kk
+ 1, ll
);
795 //logger.info("yanking >> \" > kk["+ kk +"] / ll["+ll+"] / marker["+marker+"] / subs["+subs+"]");
799 logger
.info("yanked >> id["+id
+"] / value["+subs
+"]");
802 private String
generateDbUrl(String baseUrl
, String xpath
) {
804 return baseUrl
+ xpath
;
806 public String
generateResourceName(IBob bob
) {
808 String tagName
= bob
.getTagName();
809 String id
= bob
.getAttributeValue("id");
811 return generateResourceName(tagName
, id
);
813 public String
generateResourceName(String tagName
, String idValue
) {
815 StringBuffer sbuf
= new StringBuffer(tagName
);
817 sbuf
.append(idValue
);
819 String rname
= sbuf
.toString();
820 logger
.info("Generated resource name["+rname
+"]");
824 public boolean verifyXPathMapping(String xpath
) {
826 java
.util
.Collection values
= mappings
.values();
827 return values
.contains(xpath
);
831 * strips out any predicate(s)
833 public String
stripXPath(String xpath
) {
836 * this regular expression: \\[[^\\]]*\\]
837 * matches on all content between square brackets [ ], except a right square bracket.
838 * The last condition allows multiple [ abc ] patterns in a single string
840 String bareXPath
= xpath
.replaceAll("\\[[^\\]]*\\]", "");
841 if(bareXPath
.indexOf("/") == bareXPath
.length())
842 bareXPath
= bareXPath
.substring(0, bareXPath
.lastIndexOf("/"));
848 public IBob
loadBobFromXML(String xmlString
) throws SpittoonException
{
851 logger
.debug("loadBobFromXML:: ["+ xmlString
+"]");
853 //** load a Bob object
854 InputStream istream
= null;
856 istream
= new ByteArrayInputStream(xmlString
.getBytes("UTF-8"));
858 catch(UnsupportedEncodingException e
) {
859 throw new SpittoonException(e
);
863 //System.getProperties().setProperty("bob.home", props.getProperty("bob.home"));
864 //System.getProperties().setProperty("bob.base", props.getProperty("bob.base"));
865 //System.getProperties().setProperty("bob.gen", props.getProperty("bob.gen"));
866 //System.getProperties().setProperty("bob.end", props.getProperty("bob.gen"));
867 System
.getProperties().setProperty("bob.home", "/Users/timothyw/Projects/Spittoon");
868 System
.getProperties().setProperty("bob.base", "/Users/timothyw/Projects/Spittoon");
869 System
.getProperties().setProperty("bob.gen", "/Users/timothyw/Projects/Spittoon/src/main/gen");
870 System
.getProperties().setProperty("bob.end", ".xml");
872 IBob bob
= Bob
.loadS(istream
, System
.getProperty(Util
.DEF
));
873 logger
.debug("Loaded Bob from XML" + bob
.toXML(false));
880 public static void main(String args
[]) {
882 System
.getProperties().setProperty("bob.home", "/Users/timothyw/Projects/maven.trials/Spittoon");
883 System
.getProperties().setProperty("bob.base", "/Users/timothyw/Projects/maven.trials/Spittoon");
884 System
.getProperties().setProperty("bob.gen", "/Users/timothyw/Projects/maven.trials/Spittoon/src/main/gen");
885 System
.getProperties().setProperty("bob.end", ".xml");
887 String testme
= "<group xmlns=\"com/interrupt/bookkeeping/users\" id=\"webkell\" name=\"Webkell\" owner=\"root\">" +
888 "<user id=\"root\" username=\"\" password=\"\" logintimeout=\"\" accountLevel=\"\" defaultGroup=\"\" authenticated=\"\"/>" +
891 InputStream istream
= null;
893 istream
= new ByteArrayInputStream(testme
.getBytes("UTF-8"));
895 catch(UnsupportedEncodingException e
) {
896 throw new SpittoonException(e
);
899 IBob bob
= Bob
.loadS(istream
, "src/main/resources/bookkeeping.system.xml");
900 System
.out
.println("Loaded Bob form XML" + bob
.toXML(false));
904 private static void testStripXPath() {
906 //** testing stripXPath
907 /*String origXPath = "/system[ @id=\"thing\" ]/bookkeeping[ @attr=\"value\" ]/thing";
909 Spittoon spittoon = new Spittoon();
910 String bareXPath = spittoon.stripXPath(origXPath);
911 System.out.println(bareXPath);
914 //String testme = "/system[ @id=\"blahblah blah\" ]";
915 String testme
= "/system[ @id='blahblah blah' ]";
916 System
.out
.println("Begin ["+ testme
+"]");
918 /*String sstring[] = testme.split("\\[[^\\]]*\\]");
919 for (String string : sstring) {
920 System.out.println(string);
925 private static void testYanking() {
928 String testme
= "/system[ @id='blahblah blah' ]";
930 //** test yanking 'id' attribute
931 //** make sure there's an 'id' attribute
932 int ii
= testme
.indexOf("@id");
934 String id
= testme
.substring(ii
, jj
);
936 //** find value for id attribute
937 String marker
= testme
.substring(jj
);
938 System
.out
.println("marker["+marker
+"]");
940 int kk
= marker
.indexOf("\"");
945 kk
= marker
.indexOf("'");
946 int ll
= marker
.indexOf("'", kk
+ 1);
947 subs
= marker
.substring(kk
+ 1, ll
);
949 System
.out
.println(">> ' > kk["+ kk
+"] / ll["+ll
+"] / marker["+marker
+"] / subs["+subs
+"]");
954 int ll
= marker
.indexOf("\"", kk
+ 1);
955 subs
= marker
.substring(kk
+ 1, ll
);
957 System
.out
.println(">> \" > kk["+ kk
+"] / ll["+ll
+"] / marker["+marker
+"] / subs["+subs
+"]");
961 System
.out
.println("id["+id
+"] / value["+subs
+"]");
965 class FindParentBob implements IVisitor {
967 private Logger logger = Logger.getLogger(FindParentBob.class);
968 private String tagName = null;
969 private String attributeValue = null;
970 private IBob replacement = null;
972 public String getTagName() { return tagName; }
973 public void setTagName(String tagName) { this.tagName = tagName; }
974 public String getAttributeValue() { return attributeValue; }
975 public void setAttributeValue(String attributeValue) { this.attributeValue = attributeValue; }
976 public IBob getReplacement() { return replacement; }
977 public void setReplacement(IBob replacement) { this.replacement = replacement; }
979 private boolean acceptControl = true;
980 public void visit(IBob bob) {
984 String tname = bob.getTagName();
985 String avalue = bob.getAttributeValue("id");
987 logger.debug("FindParentBob.visit > comparing tagName["+tagName+"] <=> tname["+tname+"] / attributeValue["+attributeValue+"] <=> avalue["+avalue+"]");
988 if((tagName.equals(tname)) && (attributeValue.equals(avalue))) {
990 logger.debug("FindParentBob.visit > replacing ["+bob.xpath(false)+"] with ["+replacement.toXML(false)+"]");
991 bob.replace(replacement);
992 acceptControl = false;