adding algorithm debug statements
[Spittoon.git] / src / com / interrupt / spittoon / Spittoon.java
blob126f307ce1a06faa73ea4ba9552a20fed11faac7
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;
7 import java.util.List;
8 import java.util.Properties;
9 import java.util.Set;
10 import java.util.StringTokenizer;
12 import org.xmldb.api.DatabaseManager;
13 import org.xmldb.api.base.Collection;
14 import org.xmldb.api.base.Database;
15 import org.xmldb.api.base.XMLDBException;
16 import org.xmldb.api.modules.CollectionManagementService;
17 import org.xmldb.api.modules.XMLResource;
18 import org.apache.log4j.Logger;
19 import org.exist.EXistException;
20 import org.exist.storage.BrokerPool;
21 import org.exist.util.Configuration;
22 import org.exist.util.DatabaseConfigurationException;
24 import com.interrupt.bob.base.Bob;
25 import com.interrupt.bob.base.IBob;
26 import com.interrupt.bob.util.Util;
29 public class Spittoon {
32 private String DRIVER = "org.exist.xmldb.DatabaseImpl";
33 private Properties props = new Properties();
34 private Properties mappings = new Properties();
36 private String rawDbUrl = null;
37 private String aauthDbUrl = null;
38 private String groupsDbUrl = null;
40 private String rootDir = null;
41 private String uname = null;
42 private String passwd = null;
44 private Logger logger = Logger.getLogger(Spittoon.class);
45 private Logger algorithm = Logger.getLogger("algorithm");
47 private Database databaseAauth = null;
48 private Database databaseGroups = null;
49 private Database database = null;
51 private String einitDb = null;
54 public String getAauthDbUrl() { return aauthDbUrl; }
55 public void setAauthDbUrl(String aauthDbUrl) { this.aauthDbUrl = aauthDbUrl; }
56 public String getGroupsDbUrl() { return groupsDbUrl; }
59 public void setGroupsDbUrl(String groupsDbUrl) {
60 this.groupsDbUrl = groupsDbUrl;
63 public void initialise() {
65 try {
67 //** load spittoon.properties
68 InputStream inStream = Spittoon.class.getResourceAsStream("/spittoon.properties");
69 props.load(inStream);
71 einitDb = System.getProperty("exist.initdb");
72 if(einitDb == null || einitDb.trim().length() < 1)
73 einitDb = props.getProperty("exist.initdb");
75 String ehome = System.getProperty("exist.home");
76 if(ehome == null || ehome.trim().length() < 1)
77 ehome = props.getProperty("exist.home");
79 String eSaxValidation = System.getProperty("org.xml.sax.features.validation");
80 if(eSaxValidation == null || eSaxValidation.trim().length() < 1)
81 eSaxValidation = props.getProperty("org.xml.sax.features.validation");
83 String eEndorsedDirs = System.getProperty("java.endorsed.dirs");
84 if(eEndorsedDirs == null || eEndorsedDirs.trim().length() < 1)
85 eEndorsedDirs = props.getProperty("java.endorsed.dirs");
88 logger.debug("exist.initdb["+einitDb+"] / exist.home["+ehome+
89 "] / org.xml.sax.features.validation["+eSaxValidation+"] / java.endorsed.dirs["+eEndorsedDirs+"]");
91 String db1Config = props.getProperty("db-1-config");
92 String db1Id = props.getProperty("db-1-id").trim();
93 String db1Port = props.getProperty("db-1-port");
95 String db2Config = props.getProperty("db-2-config").trim();
96 String db2Id = props.getProperty("db-2-id");
97 String db2Port = props.getProperty("db-2-port");
99 String dbSplit = props.getProperty("db-split");
101 logger.debug("Database / split["+ dbSplit +"]");
102 logger.debug("Database / config-1["+ db1Config +"] / id-1["+ db1Id +"] / port-1["+db1Port+"]");
103 logger.debug("Database / config-2["+ db2Config +"] / id-2["+ db2Id +"] / port-2["+db2Port+"]");
107 //** initialize driver
108 Class cl = Class.forName(DRIVER);
110 System.setProperty("exist.initdb", einitDb);
111 System.setProperty("exist.home", ehome);
112 System.setProperty("org.xml.sax.features.validation", eSaxValidation);
113 System.setProperty("java.endorsed.dirs", eEndorsedDirs);
115 //** extract the mappings into a separate properties object
116 extractMappings();
119 //** eXist Broker Pool properties; initialize from properties
120 rawDbUrl = props.getProperty("db.url");
121 rootDir = props.getProperty("root.dir", "root.dir");
122 uname = props.getProperty("db.uname");
123 passwd = props.getProperty("db.passwd");
125 rawDbUrl = rawDbUrl.trim();
126 rootDir = rootDir.trim();
127 uname = uname.trim();
128 passwd = passwd.trim();
130 if(einitDb.equals("true")) {
132 databaseAauth = (Database)cl.newInstance();
133 databaseAauth.setProperty("create-database", einitDb);
134 databaseAauth.setProperty("configuration", db1Config);
135 databaseAauth.setProperty("database-id", db1Id);
136 DatabaseManager.registerDatabase(databaseAauth);
137 logger.debug("EMBEDDED Database registered["+ databaseAauth.getName() +"]");
139 databaseGroups = (Database)cl.newInstance();
140 databaseGroups.setProperty("create-database", einitDb);
141 databaseGroups.setProperty("configuration", db2Config);
142 databaseGroups.setProperty("database-id", db2Id);
143 DatabaseManager.registerDatabase(databaseGroups);
144 logger.debug("EMBEDDED Database registered["+ databaseGroups.getName() +"]");
146 aauthDbUrl = rawDbUrl.replaceFirst("exist", db1Id);
147 groupsDbUrl = rawDbUrl.replaceFirst("exist", db2Id);
149 else {
151 //aauthDbUrl = rawDbUrl.replaceFirst("exist", db1Id);
152 //groupsDbUrl = rawDbUrl.replaceFirst("exist", db2Id);
153 //aauthDbUrl = aauthDbUrl.replaceFirst("8080", db1Port);
154 //groupsDbUrl = groupsDbUrl.replaceFirst("8080", db2Port);
156 database = (Database)cl.newInstance();
157 DatabaseManager.registerDatabase(database);
158 logger.debug("REMOTE Database registered["+ database.getName() +"]");
160 aauthDbUrl = rawDbUrl.replaceFirst("8080", db1Port);
161 groupsDbUrl = rawDbUrl.replaceFirst("8080", db2Port);
164 logger.debug("RawDBURL["+rawDbUrl+"] / ROOT["+rootDir+"] / UNAME["+uname+"] / PASSWD["+passwd+"]");
165 logger.debug("Aauth DBURL["+aauthDbUrl+"] / Groups DBURL["+groupsDbUrl+"]");
166 logger.debug("exist.initdb > " + System.getProperty("exist.initdb"));
168 Configuration configuration1 = null;
169 try {
171 configuration1 = new Configuration(db1Config);
173 catch(org.exist.util.DatabaseConfigurationException e) {
175 logger.error("ERROR in configuration ["+e.getMessage()+"] with file["+db1Config+"]");
177 // On error, try Tomcat specific context
178 String catalinaBase = System.getProperty("catalina.base");
179 configuration1 = new Configuration( catalinaBase + "/webapps/webkell/" + db1Config );
181 BrokerPool.configure( 1, 5, configuration1 );
183 if(dbSplit.equals("true")) {
184 Configuration configuration2 = new Configuration(db2Config);
185 BrokerPool.configure( 1, 5, configuration2 );
189 //** set Bob properties
190 System.setProperty(Util.HOME, props.getProperty("bob.home"));
191 System.setProperty(Util.BASE, props.getProperty("bob.base"));
192 System.setProperty(Util.GEN, props.getProperty("bob.gen"));
193 System.setProperty(Util.END, props.getProperty("bob.end"));
194 System.setProperty(Util.DEF, props.getProperty("bob.def"));
197 catch(DatabaseConfigurationException e) {
198 e.printStackTrace();
200 catch(EXistException e) {
201 e.printStackTrace();
203 catch(Exception e) {
204 e.printStackTrace();
209 public void setupRoot() throws SpittoonException {
211 String db1Id = props.getProperty("db-1-id");
212 String db2Id = props.getProperty("db-2-id");
214 String aauthDbUrl = rawDbUrl.replaceAll("exist", db1Id);
215 String groupsDbUrl = rawDbUrl.replaceAll("exist", db2Id);
217 createCollection(aauthDbUrl, rootDir);
218 createCollection(groupsDbUrl, rootDir);
221 public void tearDownRoot() throws SpittoonException {
223 removeCollection(aauthDbUrl, rootDir);
224 removeCollection(groupsDbUrl, rootDir);
226 try {
228 if(einitDb.equals("true")) {
230 DatabaseManager.deregisterDatabase(databaseAauth);
231 logger.debug("De-registered EMBEDED Database ["+ databaseAauth.getName() +"]");
233 DatabaseManager.deregisterDatabase(databaseGroups);
234 logger.debug("De-registered EMBEDED atabase ["+ databaseGroups.getName() +"]");
236 else {
238 DatabaseManager.deregisterDatabase(database);
239 logger.debug("De-registered REMOTE Database ["+ database.getName() +"]");
242 catch(Exception e) {
243 e.printStackTrace();
246 private Collection getCollection(String dbdirectory) throws SpittoonException {
248 logger.debug("Retrieving collection for URL["+ dbdirectory +"]");
249 Collection dbCollection = null;
250 try {
252 dbCollection = DatabaseManager.getCollection(dbdirectory, uname, passwd);
253 logger.debug("Retrieved collection["+ dbCollection.getName() +"]");
255 catch(XMLDBException e) {
256 throw new SpittoonException(e);
259 return dbCollection;
261 private Collection createCollection(String dburl, String dirname) throws SpittoonException {
263 Collection dbCollection = null;
264 Collection col = null;
265 try {
267 logger.debug("createCollection for dburl["+ dburl +"]");
269 dbCollection = DatabaseManager.getCollection(dburl, uname, passwd);
270 CollectionManagementService mgtService = (CollectionManagementService)
271 dbCollection.getService("CollectionManagementService", "1.0");
272 col = mgtService.createCollection(dirname);
273 logger.debug("Created directory["+ col.getName() +"]");
275 catch(XMLDBException e) {
276 throw new SpittoonException(e);
279 return col;
281 private void removeCollection(String dburl, String dirname) throws SpittoonException {
283 Collection dbCollection = null;
284 try {
286 dbCollection = DatabaseManager.getCollection(dburl, uname, passwd);
287 CollectionManagementService mgtService = (CollectionManagementService)
288 dbCollection.getService("CollectionManagementService", "1.0");
289 mgtService.removeCollection(dirname);
290 logger.debug("Removed directory["+ dburl + dirname +"]");
292 catch(XMLDBException e) {
293 throw new SpittoonException(e);
299 private void extractMappings() {
302 * deal with a path that is not mapped
304 Set keys = props.keySet();
305 Iterator kiter = keys.iterator();
306 String nextKey = null;
307 while(kiter.hasNext()) {
309 nextKey = (String)kiter.next();
310 if(nextKey.startsWith("mapping")) {
311 mappings.setProperty(nextKey, props.getProperty(nextKey));
317 public boolean alive() throws SpittoonException {
320 users: {
322 /**
323 * generate root collection URL string
325 StringBuffer sbuffer = new StringBuffer();
326 sbuffer.append(aauthDbUrl);
327 if(!aauthDbUrl.endsWith("/")) {
328 sbuffer.append("/");
330 sbuffer.append(rootDir);
331 String rootCollection = sbuffer.toString();
333 /**
334 * see if we have the exist 'db' collection
336 Collection dbCollection = null;
337 try {
338 dbCollection = DatabaseManager.getCollection(aauthDbUrl, uname, passwd);
339 if(dbCollection == null) {
340 throw new SpittoonException("Cannot find groups 'db' directory");
343 catch(XMLDBException xe) {
344 throw new SpittoonException(xe.getMessage(), xe.getCause());
347 /**
348 * test to see if the root collection exists
350 Collection currentCollection = null;
351 try {
352 currentCollection = DatabaseManager.getCollection(rootCollection, uname, passwd);
353 if(currentCollection == null)
354 throw new SpittoonException("root collection for aauth DB is NULL");
356 catch(XMLDBException xe) {
357 throw new SpittoonException(xe.getMessage(), xe.getCause());
360 groups: {
363 /**
364 * generate root collection URL string
366 StringBuffer sbuffer = new StringBuffer();
367 sbuffer.append(groupsDbUrl);
368 if(!groupsDbUrl.endsWith("/")) {
369 sbuffer.append("/");
371 sbuffer.append(rootDir);
372 String rootCollection = sbuffer.toString();
375 /**
376 * see if we have the exist 'db' collection
378 Collection dbCollection = null;
379 try {
380 dbCollection = DatabaseManager.getCollection(groupsDbUrl, uname, passwd);
381 if(dbCollection == null) {
382 throw new SpittoonException("Cannot find groups 'db' directory");
385 catch(XMLDBException xe) {
386 throw new SpittoonException(xe.getMessage(), xe.getCause());
389 /**
390 * test to see if the root collection exists
392 Collection currentCollection = null;
393 try {
394 currentCollection = DatabaseManager.getCollection(rootCollection, uname, passwd);
395 if(currentCollection != null)
396 return true;
398 catch(XMLDBException xe) {
399 throw new SpittoonException(xe.getMessage(), xe.getCause());
402 return false;
407 public void create(String dbUrl, String xpath, String xml) throws SpittoonException {
410 logger.debug("Spittoon.create CALLED / dbUrl["+dbUrl+"] / xpath["+xpath+"] / xml["+xml+"]");
412 //** check if xpath is mapped
413 String bareXPath = stripXPath(xpath);
414 //if(!verifyXPathMapping(bareXPath)) {
415 // throw new SpittoonException("XPath mapping ["+ bareXPath +"] not registered");
418 //** load IBob from xml
419 IBob loadedBob = loadBobFromXML(xml);
420 String tagName = loadedBob.getTagName();
421 tagName = tagName.trim();
424 //** check if we're saving the right tag
425 String targetTag = bareXPath.substring( (bareXPath.lastIndexOf("/") + 1) );
426 targetTag = targetTag.trim();
427 logger.debug("Comparing tagName["+tagName+"] to targetTag["+targetTag+"]");
428 if(!tagName.equals(targetTag))
429 throw new SpittoonException("XML supplied does not match the target xpath");
432 //** find collection from xpath
433 Collection collection = getCollectionForXPath(dbUrl, bareXPath);
434 logger.debug("Retrieved collection["+ collection +"]");
435 if(collection == null) {
437 //** generate collection
438 logger.debug("Collection is NULL / generating collection...");
439 collection = generateCollectionFromXPath(dbUrl, xpath);
440 logger.debug("Generated collection ["+ collection +"]");
443 String resourceName = generateResourceName(loadedBob);
444 try {
446 //** check if document exists
447 logger.debug("Checking if resource["+resourceName+"] exists in collection["+collection.getName()+"]");
448 XMLResource document = (XMLResource)collection.getResource(resourceName);
449 if(document == null) {
451 document = (XMLResource)collection.createResource(resourceName, "XMLResource");
452 logger.debug("Resource does NOT exist / created resource["+document.getId()+"] in collection["+collection.getName()+"]");
454 document.setContent(loadedBob.toXML(false));
456 //** save document
457 logger.debug("testing 123 - loadedBob.toXML["+loadedBob.toXML(false)+"]");
458 logger.debug("Spittoon.create:: Storing document resource > " + document.getId() + " > content["+document.getContent()+"]");
459 collection.storeResource(document);
461 catch(XMLDBException e) {
462 throw new SpittoonException(e);
464 catch(ClassCastException e) {
465 throw new SpittoonException(e);
471 public void createR(String dbUrl, String xpath, String xml) throws SpittoonException {
474 logger.debug("Spittoon.createR CALLED / dbUrl["+ dbUrl +"] / xpath["+ xpath +"] / xml["+ xml +"]");
476 //** check if xpath is mapped
477 String bareXPath = stripXPath(xpath);
478 //if(!verifyXPathMapping(bareXPath)) {
479 // throw new SpittoonException("XPath mapping ["+ bareXPath +"] not registered");
483 //** load IBob from xml
484 IBob loadedBob = loadBobFromXML(xml);
485 String tagName = loadedBob.getTagName();
486 tagName = tagName.trim();
489 //** check if we're saving the right tag
490 String targetTag = bareXPath.substring( (bareXPath.lastIndexOf("/") + 1) );
491 targetTag = targetTag.trim();
492 logger.debug("Comparing tagName["+tagName+"] to targetTag["+targetTag+"]");
493 if(!tagName.equals(targetTag))
494 throw new SpittoonException("XML supplied does not match the target xpath");
496 //**
497 this.generateCollectionFromXPath(dbUrl, xpath);
499 //** recurse through tree and save
500 List results = loadedBob.find(xpath);
501 IBob targetBob = null;
502 if(!results.isEmpty()) { // is the XML the entire block from 'system'
503 targetBob = (IBob)results.get(0);
505 else {
507 targetBob = loadedBob;
508 //String xtraPath = generateCollectionNameR(xpath, bareXPath);
509 //dbUrl += xtraPath;
510 //logger.debug("targetBob = loadedBob / xtraPath["+xtraPath+"] / dbUrl["+dbUrl+"]");
513 logger.debug("Running SaveOrUpdateVisitor on target["+ targetBob.toXML(false) +"]");
515 SaveOrUpdateVisitor suVisitor = new SaveOrUpdateVisitor(this);
516 //if(!results.isEmpty()) {
517 suVisitor.setParentXPath(
518 xpath.substring( 0,
519 (xpath.lastIndexOf("/") + 1) ));
521 suVisitor.setDbUrl(dbUrl);
523 targetBob.acceptFirst(suVisitor);
528 private Collection getCollectionForFullXPath(String dbUrl, String xpath) {
530 String bareXPath = stripXPath(xpath);
531 logger.debug("getCollectionForFullXPath:: xpath["+xpath+"] > bareXPath["+bareXPath+"]");
533 //** generate collection name
534 String colName = generateCollectionNameR(xpath, bareXPath);
535 logger.debug("getCollectionForFullXPath:: generated collection name["+ colName +"]");
537 //** get collection
538 String dbdirectory = dbUrl + rootDir +"/"+ colName;
539 Collection collection = this.getCollection(dbdirectory); // use full URL
540 logger.debug("getCollectionForFullXPath:: retrieved collection["+collection+"]");
542 return collection;
544 public IBob retrieve(String dbUrl, String xpath, boolean recurse) {
546 algorithm.debug(""); algorithm.debug("");
547 algorithm.debug("retrieve CALLED > params("+dbUrl+","+xpath+","+recurse+")");
549 /******
550 * check if there's a child document
552 String bareXPath = stripXPath(xpath);
553 logger.debug("retrieve:: xpath["+xpath+"] > bareXPath["+bareXPath+"]");
555 //** generate collection name
556 String colName = generateCollectionNameR(xpath, bareXPath);
557 logger.debug("retrieve:: generated collection name["+ colName +"]");
559 //** get collection
560 String dbdirectory = dbUrl + rootDir +"/"+ colName;
561 Collection collection = this.getCollection(dbdirectory); // use full URL
564 /******
565 * check if there's a child document
567 logger.debug("Retrieving for > dbUrl["+ dbUrl +"] / xpath["+ xpath +"]");
568 Collection collection = getCollectionForFullXPath(dbUrl, xpath);
570 //** child resource will be named the same as the directory
571 IBob resultBob = null;
572 try {
574 String rname = collection.getName();
575 rname = rname.substring(rname.lastIndexOf("/") + 1);
576 XMLResource eachResource = (XMLResource)collection.getResource(rname);
577 algorithm.debug("retrieve > Child resource ["+ eachResource.getContent() +"] > forName["+rname+"] > inCollection["+collection.getName()+"]");
579 if(eachResource == null) {
580 throw new SpittoonException("NULL child resource in directory ["+ collection.getName()+"]");
583 /******
584 * if yes, then i) add to parent 'bob' ii) set as parent 'bob'
586 resultBob = this.loadBobFromXML((String)eachResource.getContent());
587 algorithm.debug("retrieve > LOADED Child resource ["+ resultBob +"] > xpath["+ resultBob.xpath(true) +"]");
589 /*if(parent != null) {
591 FindParentBob fpvisitor = new FindParentBob();
592 fpvisitor.setTagName(resultBob.getTagName());
593 fpvisitor.setAttributeValue(resultBob.getAttributeValue("id"));
594 fpvisitor.setReplacement(resultBob);
595 parent.acceptFirst(fpvisitor); //** i)
597 logger.debug("OK > new parent after replace... " + parent.toXML(false));
602 //** should we recurse
603 if(recurse) {
605 algorithm.debug("retrieve > IN recurse block");
607 //** get child collections
608 String[] childCollections = collection.listChildCollections();
609 IBob eachBob = null;
610 for (String string : childCollections) {
612 algorithm.debug("retrieve > EACH ");
614 //** for each child collection, recurse to it's children
615 String tname = string.substring(0, string.indexOf("."));
616 String idvalue = string.substring(string.indexOf(".") + 1);
618 StringBuffer sbuf = new StringBuffer(xpath);
619 sbuf.append("/");
620 sbuf.append(tname);
621 sbuf.append("[ ");
622 sbuf.append("@id='");
623 sbuf.append(idvalue);
624 sbuf.append("' ]");
626 //** next XML retrieved
627 String eachXPath = sbuf.toString();
628 algorithm.debug("retrieve > EACH childCollection string["+string+"] > created XPath["+eachXPath+"]");
630 algorithm.debug("IN recurse");
631 eachBob = retrieve(dbUrl, eachXPath, recurse); //** ii)
632 algorithm.debug("OUT recurse");
634 boolean removed = resultBob.remove(eachBob.getTagName(), "id", eachBob.getAttributeValue("id"));
635 algorithm.debug("["+removed+"] removed '"+eachBob.getTagName()+"[@id='"+eachBob.getAttributeValue("id")+"']");
637 resultBob.addChild(eachBob);
643 catch(XMLDBException e) {
644 throw new SpittoonException(e);
647 return resultBob;
650 public Collection getCollectionForXPath(String dbUrl, String bareXPath) throws SpittoonException {
653 //if(!verifyXPathMapping(bareXPath)) {
654 // throw new SpittoonException("XPath ["+ bareXPath +"] is not mapped");
657 String eurl = generateDbUrl((dbUrl + rootDir), bareXPath);
658 logger.debug("getCollectionForXPath:: Generated eurl["+ eurl +"]");
660 Collection collection = null;
661 try {
662 collection = DatabaseManager.getCollection(eurl, uname, passwd);
664 catch(XMLDBException e) {
665 throw new SpittoonException(e.getMessage(), e);
668 return collection;
671 public Collection generateCollectionFromXPath(String dbUrl, String xpath) throws SpittoonException {
673 logger.debug("Spittoon.generateCollectionFromXPath:: dbUrl["+ dbUrl +"] / xpath["+ xpath +"]");
674 String bareXPath = stripXPath(xpath);
676 //if(!verifyXPathMapping(bareXPath)) {
677 // throw new SpittoonException("XPath ["+ bareXPath +"] is not mapped");
680 String baseName = dbUrl + rootDir;
681 String eurl = dbUrl + rootDir;
682 logger.debug("generateCollectionFromXPath:: Generated rootUrl["+ eurl +"]");
685 StringTokenizer stokenizer = new StringTokenizer( bareXPath, "/" );
686 StringTokenizer xpathTokenizer = new StringTokenizer( xpath, "/" ); //** mirroring stokenizer in loop ** It's bad, I know, I knooowwww **
687 Collection nextCollection = null;
688 try {
690 //** this should be the root collection
691 nextCollection = DatabaseManager.getCollection(eurl, uname, passwd);
692 //logger.debug("1. Next collection["+ nextCollection +"]");
693 if(nextCollection == null)
694 throw new SpittoonException("There is no root collection["+ eurl +"]");
696 String nextToken = stokenizer.nextToken();
697 String nextXPath = xpathTokenizer.nextToken();
698 String previousUrl = null;
700 //logger.debug("1. nextToken ["+ nextToken +"] / nextXPath["+ nextXPath +"]");
702 boolean moreTokens = false;
703 if(nextToken != null)
704 moreTokens = true;
707 //String checkMappingS = "";
709 while((nextCollection != null) && moreTokens) {
711 previousUrl = eurl;
713 logger.debug("nextToken["+nextToken +"] / nextXPath["+ nextXPath +"]");
714 String colName = generateNextCollectionName(nextToken, nextXPath);
715 eurl += "/" + colName;
717 /** check if collection is mapped
718 checkMappingS += "/" + nextToken;
719 logger.debug("generateCollectionFromXPath:: verifying mapping > ["+ verifyXPathMapping(checkMappingS) +"] > ["+ checkMappingS +"]");
721 if(!verifyXPathMapping(checkMappingS)) {
723 //** if xpath is not mapped, do not create a collection
725 //** KLUDGE 1 - some control stuff
726 if(stokenizer.hasMoreTokens()) {
727 moreTokens = true;
728 nextToken = stokenizer.nextToken();
729 nextXPath = xpathTokenizer.nextToken();
731 else {
732 moreTokens = false;
734 continue;
738 mainbit: {
740 logger.debug("Looking for the next collection["+eurl+"]");
742 nextCollection = DatabaseManager.getCollection(eurl, uname, passwd);
743 if(nextCollection == null) {
745 logger.debug(">> didn't find the last collection / eurl["+eurl+"]... creating previousUrl["+previousUrl+"] / collection name["+colName+"]");
746 nextCollection = createCollection(previousUrl, colName);
747 logger.debug(">> Created the next collection["+ nextCollection +"] / url["+ previousUrl +"/"+ colName +"]");
752 //** KLUDGE 2
753 if(stokenizer.hasMoreTokens()) {
754 moreTokens = true;
755 nextToken = stokenizer.nextToken();
756 nextXPath = xpathTokenizer.nextToken();
757 //logger.debug("2. nextToken ["+ nextToken +"]");
759 else {
760 moreTokens = false;
764 catch(XMLDBException e) {
765 throw new SpittoonException(e.getMessage(), e);
768 return nextCollection;
771 private String generateCollectionNameR(String xpath, String bareXPath) {
774 StringTokenizer xtokenizer = new StringTokenizer(xpath, "/");
775 StringTokenizer btokenizer = new StringTokenizer(bareXPath, "/");
777 String eachx = null;
778 String eachb = null;
779 String eachPart = null;
780 StringBuffer sbuffer = new StringBuffer();
782 while(xtokenizer.hasMoreTokens()) {
784 eachx = xtokenizer.nextToken();
785 eachb = btokenizer.nextToken();
787 eachPart = generateNextCollectionName(eachb, eachx);
788 logger.info("generateCollectionNameR:: eachx["+ eachx +"] > eachb["+ eachb +"] > eachPart["+ eachPart +"]");
790 sbuffer.append(eachPart);
791 if(xtokenizer.hasMoreTokens())
792 sbuffer.append("/");
794 String resultName = sbuffer.toString();
795 logger.info("generateCollectionNameR:: result["+ resultName +"]");
797 return resultName;
799 private String generateNextCollectionName(String nextToken, String nextXPath) {
801 String yvalue = yankAttributeId(nextXPath);
802 logger.info("generating Collection name / nextXPath ["+ nextXPath +"] / yanked 'id' value ["+ yvalue +"] ...");
804 return nextToken + "." + yvalue;
806 private String yankAttributeId(String attributeString) {
808 logger.debug("yankAttributeId["+ attributeString +"]");
810 //** test yanking 'id' attribute
811 //** make sure there's an 'id' attribute
812 int ii = attributeString.indexOf("@id");
813 int jj = (ii + 3);
814 String id = null;
815 try {
816 attributeString.substring(ii, jj);
818 catch(StringIndexOutOfBoundsException e) {
819 throw new SpittoonException("No 'id' attribute specified for ["+ attributeString +"]", e);
822 //** find value for id attribute
823 String marker = attributeString.substring(jj);
824 //logger.info("yanking marker["+marker+"]");
826 int kk = marker.indexOf("\"");
828 String subs = null;
829 if(kk == -1) {
831 kk = marker.indexOf("'");
832 int ll = marker.indexOf("'", kk + 1);
833 subs = marker.substring(kk + 1, ll);
835 //logger.info("yanking >> ' > kk["+ kk +"] / ll["+ll+"] / marker["+marker+"] / subs["+subs+"]");
838 else {
840 int ll = marker.indexOf("\"", kk + 1);
841 subs = marker.substring(kk + 1, ll);
843 //logger.info("yanking >> \" > kk["+ kk +"] / ll["+ll+"] / marker["+marker+"] / subs["+subs+"]");
847 logger.info("yanked >> id["+id+"] / value["+subs+"]");
848 return subs;
850 private String generateDbUrl(String baseUrl, String xpath) {
852 return baseUrl + xpath;
854 public String generateResourceName(IBob bob) {
856 String tagName = bob.getTagName();
857 String id = bob.getAttributeValue("id");
859 return generateResourceName(tagName, id);
861 public String generateResourceName(String tagName, String idValue) {
863 StringBuffer sbuf = new StringBuffer(tagName);
864 sbuf.append(".");
865 sbuf.append(idValue);
867 String rname = sbuf.toString();
868 logger.info("Generated resource name["+rname+"]");
869 return rname;
872 public boolean verifyXPathMapping(String xpath) {
874 java.util.Collection values = mappings.values();
875 return values.contains(xpath);
879 * strips out any predicate(s)
881 public String stripXPath(String xpath) {
884 * this regular expression: \\[[^\\]]*\\]
885 * matches on all content between square brackets [ ], except a right square bracket.
886 * The last condition allows multiple [ abc ] patterns in a single string
888 String bareXPath = xpath.replaceAll("\\[[^\\]]*\\]", "");
889 if(bareXPath.indexOf("/") == bareXPath.length())
890 bareXPath = bareXPath.substring(0, bareXPath.lastIndexOf("/"));
892 return bareXPath;
896 public IBob loadBobFromXML(String xmlString) throws SpittoonException {
899 logger.debug("loadBobFromXML:: ["+ xmlString +"]");
901 //** load a Bob object
902 InputStream istream = null;
903 try {
904 istream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
906 catch(UnsupportedEncodingException e) {
907 throw new SpittoonException(e);
911 //System.getProperties().setProperty("bob.home", props.getProperty("bob.home"));
912 //System.getProperties().setProperty("bob.base", props.getProperty("bob.base"));
913 //System.getProperties().setProperty("bob.gen", props.getProperty("bob.gen"));
914 //System.getProperties().setProperty("bob.end", props.getProperty("bob.gen"));
915 System.getProperties().setProperty("bob.home", "/Users/timothyw/Projects/Spittoon");
916 System.getProperties().setProperty("bob.base", "/Users/timothyw/Projects/Spittoon");
917 System.getProperties().setProperty("bob.gen", "/Users/timothyw/Projects/Spittoon/src/main/gen");
918 System.getProperties().setProperty("bob.end", ".xml");
920 IBob bob = Bob.loadS(istream, System.getProperty(Util.DEF));
921 logger.debug("Loaded Bob from XML" + bob.toXML(false));
923 return bob;
928 public static void main(String args[]) {
930 System.getProperties().setProperty("bob.home", "/Users/timothyw/Projects/maven.trials/Spittoon");
931 System.getProperties().setProperty("bob.base", "/Users/timothyw/Projects/maven.trials/Spittoon");
932 System.getProperties().setProperty("bob.gen", "/Users/timothyw/Projects/maven.trials/Spittoon/src/main/gen");
933 System.getProperties().setProperty("bob.end", ".xml");
935 String testme = "<group xmlns=\"com/interrupt/bookkeeping/users\" id=\"webkell\" name=\"Webkell\" owner=\"root\">" +
936 "<user id=\"root\" username=\"\" password=\"\" logintimeout=\"\" accountLevel=\"\" defaultGroup=\"\" authenticated=\"\"/>" +
937 "</group>";
939 InputStream istream = null;
940 try {
941 istream = new ByteArrayInputStream(testme.getBytes("UTF-8"));
943 catch(UnsupportedEncodingException e) {
944 throw new SpittoonException(e);
947 IBob bob = Bob.loadS(istream, "src/main/resources/bookkeeping.system.xml");
948 System.out.println("Loaded Bob form XML" + bob.toXML(false));
952 private static void testStripXPath() {
954 //** testing stripXPath
955 /*String origXPath = "/system[ @id=\"thing\" ]/bookkeeping[ @attr=\"value\" ]/thing";
957 Spittoon spittoon = new Spittoon();
958 String bareXPath = spittoon.stripXPath(origXPath);
959 System.out.println(bareXPath);
962 //String testme = "/system[ @id=\"blahblah blah\" ]";
963 String testme = "/system[ @id='blahblah blah' ]";
964 System.out.println("Begin ["+ testme +"]");
966 /*String sstring[] = testme.split("\\[[^\\]]*\\]");
967 for (String string : sstring) {
968 System.out.println(string);
973 private static void testYanking() {
976 String testme = "/system[ @id='blahblah blah' ]";
978 //** test yanking 'id' attribute
979 //** make sure there's an 'id' attribute
980 int ii = testme.indexOf("@id");
981 int jj = (ii + 3);
982 String id = testme.substring(ii, jj);
984 //** find value for id attribute
985 String marker = testme.substring(jj);
986 System.out.println("marker["+marker+"]");
988 int kk = marker.indexOf("\"");
990 String subs = null;
991 if(kk == -1) {
993 kk = marker.indexOf("'");
994 int ll = marker.indexOf("'", kk + 1);
995 subs = marker.substring(kk + 1, ll);
997 System.out.println(">> ' > kk["+ kk +"] / ll["+ll+"] / marker["+marker+"] / subs["+subs+"]");
1000 else {
1002 int ll = marker.indexOf("\"", kk + 1);
1003 subs = marker.substring(kk + 1, ll);
1005 System.out.println(">> \" > kk["+ kk +"] / ll["+ll+"] / marker["+marker+"] / subs["+subs+"]");
1009 System.out.println("id["+id+"] / value["+subs+"]");
1013 class FindParentBob implements IVisitor {
1015 private Logger logger = Logger.getLogger(FindParentBob.class);
1016 private String tagName = null;
1017 private String attributeValue = null;
1018 private IBob replacement = null;
1020 public String getTagName() { return tagName; }
1021 public void setTagName(String tagName) { this.tagName = tagName; }
1022 public String getAttributeValue() { return attributeValue; }
1023 public void setAttributeValue(String attributeValue) { this.attributeValue = attributeValue; }
1024 public IBob getReplacement() { return replacement; }
1025 public void setReplacement(IBob replacement) { this.replacement = replacement; }
1027 private boolean acceptControl = true;
1028 public void visit(IBob bob) {
1030 if(acceptControl) {
1032 String tname = bob.getTagName();
1033 String avalue = bob.getAttributeValue("id");
1035 logger.debug("FindParentBob.visit > comparing tagName["+tagName+"] <=> tname["+tname+"] / attributeValue["+attributeValue+"] <=> avalue["+avalue+"]");
1036 if((tagName.equals(tname)) && (attributeValue.equals(avalue))) {
1038 logger.debug("FindParentBob.visit > replacing ["+bob.xpath(false)+"] with ["+replacement.toXML(false)+"]");
1039 bob.replace(replacement);
1040 acceptControl = false;