This transformer allows to perform resource creation, deletion, and
XUpdate command execution in XML:DB. All operations are performed either
in
element. Context collection must be specified relative to the base collection.
The component configuration defined in <map:transformer> can be
overriden with sitemap parameters on the <map:transform>:
| Method from org.apache.cocoon.transformation.XMLDBTransformer Detail: |
public void characters(char[] c,
int start,
int len) throws SAXException {
if (!processing) {
super.characters(c,start,len);
} else if (this.queryHandler != null) {
this.queryHandler.characters(c,start,len);
}
}
Receive notification of character data. |
public void comment(char[] ch,
int start,
int len) throws SAXException {
if (!processing) {
super.comment(ch, start, len);
} else if (this.queryHandler != null) {
this.queryHandler.comment(ch, start, len);
}
}
Report an XML comment anywhere in the document. |
public void configure(Configuration configuration) throws ConfigurationException {
this.driver = configuration.getChild("driver").getValue(null);
if (driver == null) {
getLogger().debug("Driver parameter is missing. Transformer will not initialize database.");
}
this.default_base = configuration.getChild("base").getValue(null);
this.default_user = configuration.getChild("user").getValue(null);
this.default_password = configuration.getChild("password").getValue(null);
}
|
public void endCDATA() throws SAXException {
if (!processing) {
super.endCDATA();
} else if (this.queryHandler != null) {
this.queryHandler.endCDATA();
}
}
Report the end of a CDATA section. |
public void endDTD() throws SAXException {
if (!processing) {
super.endDTD();
} else {
throw new SAXException("Recieved endDTD after xmldb element.");
}
}
Report the end of DTD declarations. |
public void endDocument() throws SAXException {
super.endDocument();
}
Receive notification of the end of a document. |
public void endElement(String uri,
String loc,
String raw) throws SAXException {
if (!processing) {
super.endElement(uri,loc,raw);
} else {
if (XMLDB_URI.equals(uri) && XMLDB_QUERY_ELEMENT.equals(loc)) {
processing = false;
String document = null;
if (this.queryHandler != null) {
// Finish building query. Remove existing prefix mappings.
Iterator i = prefixMap.entrySet().iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry) i.next();
this.queryHandler.endPrefixMapping((String)entry.getKey());
}
this.queryHandler.endDocument();
document = this.queryWriter.toString();
}
// Perform operation
Collection collection = null;
try {
// Obtain collection for the current operation
collection = (xbase != null)? DatabaseManager.getCollection(local_base + "/" + xbase, this.local_user, this.local_password) : this.collection;
if (collection == null) {
message = "Failed to " + operation + " resource " + this.key + ": Collection " + local_base + "/" + xbase + " not found.";
getLogger().debug(message);
} else if ("create".equals(operation)) {
if (key != null && key.endsWith("/")) {
try {
// Cut trailing '/'
String k = this.key.substring(0, this.key.length() - 1);
CollectionManagementService service =
(CollectionManagementService) collection.getService("CollectionManagementService", "1.0");
service.createCollection(k);
result = "success";
} catch (XMLDBException e) {
message = "Failed to create collection " + this.key + ": " + e.errorCode;
getLogger().error(message, e);
}
} else {
try {
if (key == null) {
key = collection.createId();
}
// Support of binary objects can be added. Content can be obtained using Source.
Resource resource = collection.createResource(key, "XMLResource");
resource.setContent(document);
collection.storeResource(resource);
result = "success";
key = resource.getId();
} catch (XMLDBException e) {
message = "Failed to create resource " + key + ": " + e.errorCode;
getLogger().debug(message, e);
}
}
} else if ("delete".equals(operation)) {
if (key != null && key.endsWith("/")) {
try {
// Cut trailing '/'
String k = this.key.substring(0, this.key.length() - 1);
CollectionManagementService service =
(CollectionManagementService) collection.getService("CollectionManagementService", "1.0");
service.removeCollection(k);
result = "success";
} catch (XMLDBException e) {
message = "Failed to delete collection " + this.key + ": " + e.errorCode;
getLogger().error(message, e);
}
} else {
try {
Resource resource = collection.getResource(this.key);
if (resource == null) {
message = "Resource " + this.key + " does not exist";
getLogger().debug(message);
} else {
collection.removeResource(resource);
result = "success";
}
} catch (XMLDBException e) {
message = "Failed to delete resource " + key + ": " + e.errorCode;
getLogger().debug(message, e);
}
}
} else if ("update".equals(operation)) {
try {
XUpdateQueryService service =
(XUpdateQueryService) collection.getService("XUpdateQueryService", "1.0");
long count = (this.key == null)?
service.update(document) : service.updateResource(this.key, document);
message = count + " entries updated.";
result = "success";
} catch (XMLDBException e) {
message = "Failed to update resource " + key + ": " + e.errorCode;
getLogger().debug(message, e);
}
}
} catch (XMLDBException e) {
message = "Failed to get context collection for the query (base: " + local_base + ", context: " + xbase + "): " + e.errorCode;
getLogger().debug(message, e);
} finally {
if (xbase != null && collection != null) {
try {
collection.close();
} catch (XMLDBException ignored) {
}
}
}
// Report result
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute("", XMLDB_QUERY_OID_ATTRIBUTE,
XMLDB_QUERY_OID_ATTRIBUTE, "CDATA", this.key);
attrs.addAttribute("", XMLDB_QUERY_TYPE_ATTRIBUTE,
XMLDB_QUERY_TYPE_ATTRIBUTE, "CDATA", this.operation);
attrs.addAttribute("", XMLDB_QUERY_RESULT_ATTRIBUTE,
XMLDB_QUERY_RESULT_ATTRIBUTE, "CDATA", result);
super.startElement(uri, loc, raw, attrs);
if (message != null) {
super.characters(message.toCharArray(), 0, message.length());
}
super.endElement(uri, loc, raw);
} else if (this.queryHandler != null) {
this.queryHandler.endElement(uri, loc, raw);
}
}
}
Receive notification of the end of an element. |
public void endEntity(String name) throws SAXException {
if (!processing) {
super.endEntity(name);
} else if (this.queryHandler != null) {
this.queryHandler.endEntity(name);
}
}
Report the end of an entity. |
public void endPrefixMapping(String prefix) throws SAXException {
if (!processing) {
super.endPrefixMapping(prefix);
prefixMap.remove(prefix);
} else if (this.queryHandler != null){
this.queryHandler.endPrefixMapping(prefix);
}
}
End the scope of a prefix-URI mapping. |
public Serializable getKey() {
return null;
}
Generate the unique key.
This key must be unique inside the space of this component.
This method must be invoked before the generateValidity() method. |
protected SAXTransformerFactory getTransformerFactory() {
if (tfactory == null) {
tfactory = (SAXTransformerFactory) TransformerFactory.newInstance();
tfactory.setErrorListener(new TraxErrorHandler(getLogger()));
}
return tfactory;
}
Helper for TransformerFactory. |
public SourceValidity getValidity() {
return null;
}
Generate the validity object.
Before this method can be invoked the generateKey() method
must be invoked. |
public void ignorableWhitespace(char[] c,
int start,
int len) throws SAXException {
if (!processing) {
super.ignorableWhitespace(c,start,len);
} else if (this.queryHandler != null) {
this.queryHandler.ignorableWhitespace(c,start,len);
}
}
Receive notification of ignorable whitespace in element content. |
public void initialize() throws Exception {
if (driver != null) {
Class c = Class.forName(driver);
Database database = (Database)c.newInstance();
DatabaseManager.registerDatabase(database);
}
}
Initializes XML:DB database instance if driver class was configured. |
public void processingInstruction(String target,
String data) throws SAXException {
if (!processing) {
super.processingInstruction(target,data);
} else if (this.queryHandler != null) {
this.queryHandler.processingInstruction(target,data);
}
}
Receive notification of a processing instruction. |
public void recycle() {
this.prefixMap.clear();
this.queryHandler = null;
this.queryWriter = null;
try {
if (collection != null) {
collection.close();
}
} catch (XMLDBException e) {
getLogger().error("Failed to close collection " + this.local_base + ". Error " + e.errorCode, e);
}
collection = null;
super.recycle();
}
|
public void setup(SourceResolver resolver,
Map objectModel,
String src,
Parameters par) throws IOException, SAXException, ProcessingException {
this.local_base = par.getParameter("base", this.default_base);
if (this.local_base == null) {
throw new ProcessingException("Required base parameter is missing. Syntax is: xmldb:xindice:///db/collection");
}
/** Get user password from parameter for the database. Usefull for update action */
this.local_user = par.getParameter("user", this.default_user);
this.local_password = par.getParameter("password", this.default_password);
try {
this.collection = DatabaseManager.getCollection(this.local_base, this.local_user, this.local_password);
} catch (XMLDBException e) {
throw new ProcessingException("Could not get collection " + this.local_base + ": " + e.errorCode, e);
}
if (this.collection == null) {
throw new ResourceNotFoundException("Collection " + this.local_base + " does not exist");
}
}
|
public void skippedEntity(String name) throws SAXException {
if (!processing) {
super.skippedEntity(name);
} else if (this.queryHandler != null) {
this.queryHandler.skippedEntity(name);
}
}
Receive notification of a skipped entity. |
public void startCDATA() throws SAXException {
if (!processing) {
super.startCDATA();
} else if (this.queryHandler != null) {
this.queryHandler.startCDATA();
}
}
Report the start of a CDATA section. |
public void startDTD(String name,
String publicId,
String systemId) throws SAXException {
if (!processing) {
super.startDTD(name, publicId, systemId);
} else {
throw new SAXException(
"Recieved startDTD after beginning SVG extraction process."
);
}
}
Report the start of DTD declarations, if any. |
public void startDocument() throws SAXException {
super.startDocument();
}
Receive notification of the beginning of a document. |
public void startElement(String uri,
String loc,
String raw,
Attributes a) throws SAXException {
if (!processing) {
if (XMLDB_URI.equals(uri) && XMLDB_QUERY_ELEMENT.equals(loc)){
this.operation = a.getValue(XMLDB_QUERY_TYPE_ATTRIBUTE);
if (!"create".equals(operation) && !"delete".equals(operation) && !"update".equals(operation)) {
throw new SAXException("Supported operation types are: create, delete, update");
}
this.key = a.getValue(XMLDB_QUERY_OID_ATTRIBUTE);
if ("delete".equals(operation) && this.key == null) {
throw new SAXException("Object ID attribute is missing on query element");
}
this.xbase = a.getValue(XMLDB_QUERY_CONTEXT_ATTRIBUTE);
// Start processing
result = "failure";
message = null;
processing = true;
if ("create".equals(operation) && this.key != null && this.key.endsWith("/")) {
} else if (!"delete".equals(operation)) {
// Prepare SAX query writer
queryWriter = new StringWriter(256);
try {
this.queryHandler = getTransformerFactory().newTransformerHandler();
this.queryHandler.setResult(new StreamResult(queryWriter));
this.queryHandler.getTransformer().setOutputProperties(format);
} catch (TransformerConfigurationException e) {
throw new SAXException("Failed to get transformer handler", e);
}
// Start query document
this.queryHandler.startDocument();
Iterator i = prefixMap.entrySet().iterator();
while (i.hasNext()) {
Map.Entry entry = (Map.Entry)i.next();
this.queryHandler.startPrefixMapping((String)entry.getKey(), (String)entry.getValue());
}
}
} else {
super.startElement(uri, loc, raw, a);
}
} else if (this.queryHandler != null) {
this.queryHandler.startElement(uri, loc, raw, a);
}
}
Receive notification of the beginning of an element. |
public void startEntity(String name) throws SAXException {
if (!processing) {
super.startEntity(name);
} else if (this.queryHandler != null) {
this.queryHandler.startEntity(name);
}
}
Report the beginning of an entity. |
public void startPrefixMapping(String prefix,
String uri) throws SAXException {
if (!processing) {
super.startPrefixMapping(prefix,uri);
prefixMap.put(prefix,uri);
} else if (this.queryHandler != null) {
this.queryHandler.startPrefixMapping(prefix, uri);
}
}
Begin the scope of a prefix-URI Namespace mapping. |