}
protected Object unmarshallDocument( Class clazz, String path, String extension ) throws DocumentNotFoundException,
DocumentException
{
Document document = null;
File f = null;
if (path.endsWith(extension))
{
f = new File(this.documentRootDir, path);
}
else
{
f = new File(this.documentRootDir, path + extension);
}
if (!f.exists())
{
throw new PageNotFoundException("Document not found: " + path);
}
try
{
// unmarshal: use SAX II parser to read document XML, filtering
// for page and folder menu definition menu elements ordered
// polymorphic collection to insert artifical <menu-element>
// and <fragment-element> tags enabling Castor XML binding;
// see JETSPEED-INF/castor/page-mapping.xml
final InputSource readerInput = new InputSource(new InputStreamReader(new FileInputStream(f), PSML_DOCUMENT_ENCODING));
Unmarshaller unmarshaller = new Unmarshaller();
unmarshaller.setResolver((XMLClassDescriptorResolver) classDescriptorResolver);
unmarshaller.setValidation(false); // results in better performance
synchronized (xmlReader)
{
document = (Document) unmarshaller.unmarshal(new SAX2EventProducer()
{
public void setContentHandler(final ContentHandler handler)
{
xmlReader.setContentHandler(new ContentHandler()
{
private int menuDepth = 0;
public void characters(char[] ch, int start, int length) throws SAXException
{
handler.characters(ch, start, length);
}
public void endDocument() throws SAXException
{
handler.endDocument();
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
handler.ignorableWhitespace(ch, start, length);
}
public void processingInstruction(String target, String data) throws SAXException
{
handler.processingInstruction(target, data);
}
public void setDocumentLocator(Locator locator)
{
handler.setDocumentLocator(locator);
}
public void startDocument() throws SAXException
{
handler.startDocument();
}
public void endElement(String uri, String localName, String qName) throws SAXException
{
// always include all elements
handler.endElement(uri,localName,qName);
// track menu depth and insert menu-element nodes
// to encapsulate menu elements to support collection
// polymorphism in Castor
if (qName.equals("menu"))
{
menuDepth--;
if (menuDepth > 0)
{
handler.endElement(null,null,"menu-element");
}
}
else if ((menuDepth > 0) &&
(qName.equals("options") || qName.equals("separator") ||
qName.equals("include") || qName.equals("exclude")))
{
handler.endElement(null,null,"menu-element");
}
// insert fragment-element nodes to encapsulate
// fragment elements to support collection
// polymorphism in Castor
if (qName.equals("fragment") || qName.equals("fragment-reference") || qName.equals("page-fragment"))
{
handler.endElement(null,null,"fragment-element");
}
}
public void endPrefixMapping(String prefix) throws SAXException
{
}
public void skippedEntity(String name) throws SAXException
{
handler.skippedEntity(name);
}
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException
{
// track menu depth and insert menu-element nodes
// to encapsulate menu elements to support collection
// polymorphism in Castor
if (qName.equals("menu"))
{
if (menuDepth > 0)
{
handler.startElement(null,null,"menu-element", null);
}
menuDepth++;
}
else if ((menuDepth > 0) &&
(qName.equals("options") || qName.equals("separator") ||
qName.equals("include") || qName.equals("exclude")))
{
handler.startElement(null,null,"menu-element", null);
}
// insert fragment-element nodes to encapsulate
// fragment elements to support collection
// polymorphism in Castor
if (qName.equals("fragment") || qName.equals("fragment-reference") || qName.equals("page-fragment"))
{
handler.startElement(null,null,"fragment-element",null);
}
// always include all elements
handler.startElement(null,null, qName, atts);
}
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
}
});
}
public void start() throws SAXException
{
try
{
xmlReader.parse(readerInput);
}
catch (IOException ioe)
{
throw new SAXException(ioe);
}
}
});
}
document.setPath(path);
AbstractBaseElement documentImpl = (AbstractBaseElement)document;
documentImpl.setHandlerFactory(handlerFactory);
documentImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
documentImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
boolean dirty = documentImpl.unmarshalled(generator);
if (dirty || document.isDirty()){
updateDocument(document, true);
document.setDirty(false);
}
}
catch (IOException e)
{
log.error("Could not load the file " + f.getAbsolutePath(), e);
throw new PageNotFoundException("Could not load the file " + f.getAbsolutePath(), e);
}
catch (MarshalException e)
{
log.error("Could not unmarshal the file " + f.getAbsolutePath(), e);
throw new PageNotFoundException("Could not unmarshal the file " + f.getAbsolutePath(), e);
}
catch (ValidationException e)
{
log.error("Document " + f.getAbsolutePath() + " is not valid", e);
throw new DocumentNotFoundException("Document " + f.getAbsolutePath() + " is not valid", e);
}
if (document == null)
{
throw new DocumentNotFoundException("Document not found: " + path);
}
else
{
if (!clazz.isAssignableFrom(document.getClass()))
{
throw new ClassCastException(document.getClass().getName() + " must implement or extend "
+ clazz.getName());
}
return document;
}
}