Index: components/page-manager/project.xml
===================================================================
--- components/page-manager/project.xml (revision 551254)
+++ components/page-manager/project.xml (working copy)
@@ -88,7 +88,8 @@
- **/PageManagerTestShared.java
+ **/PageManagerTestShared.javav
+ **/DirectoryXMLTransform.java
Index: components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java
===================================================================
--- components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java (revision 0)
+++ components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java (revision 0)
@@ -0,0 +1,205 @@
+/**
+ *
+ */
+package org.apache.jetspeed.page;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.nio.channels.FileChannel;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jetspeed.util.DirectoryHelper;
+
+
+/**
+ * @author ddam
+ *
+ */
+public class DirectoryXMLTransform extends DirectoryHelper
+{
+ private SAXTransformerFactory transformerFactory;
+
+ private SAXParserFactory saxFactory;
+
+ private Map xsltMapping;
+
+ public DirectoryXMLTransform(File base, Map extensionToXslt) {
+ super(base);
+ this.xsltMapping=extensionToXslt;
+ System.setProperty("javax.xml.transform.TransformerFactory",
+ "org.apache.xalan.processor.TransformerFactoryImpl");
+ System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
+ System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
+ transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+ saxFactory = SAXParserFactory.newInstance();
+ saxFactory.setValidating(false);
+
+ }
+
+ protected void setBaseDirectory(File directory){
+ if(!directory.exists())
+ {
+ directory.mkdirs();
+ }
+
+ if(!directory.isDirectory())
+ {
+ throw new IllegalArgumentException("DirectoryHelper(File) requires directory not a file.");
+ }
+ this.directory = directory;
+
+ }
+
+ private Transformer getXSLTForFile(File f){
+ String extension = StringUtils.substringAfterLast(f.getName(),".");
+
+ if (!StringUtils.isEmpty(extension) && xsltMapping.containsKey(extension.toLowerCase())){
+
+ Object t_obj = xsltMapping.get(extension.toLowerCase());
+ if (t_obj instanceof Transformer){
+ return (Transformer)t_obj;
+ }
+ if (t_obj instanceof String){
+ String t_path = (String) t_obj;
+ Transformer transformer;
+ try{
+ transformer = transformerFactory.newTransformer(new StreamSource(t_path));
+ xsltMapping.put(extension, transformer);
+ return transformer;
+ } catch(TransformerConfigurationException e){
+
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * copyFrom
+ *
+ *
+ * @see org.apache.jetspeed.util.FileSystemHelper#copyFrom(java.io.File, java.io.FileFilter)
+ * @param directory
+ * @param fileFilter
+ * @throws IOException
+ */
+ public void copyFromAndTransform( File srcDirectory, FileFilter fileFilter ) throws IOException
+ {
+ if(!srcDirectory.isDirectory())
+ {
+ throw new IllegalArgumentException("DirectoryHelper.copyFrom(File) requires directory not a file.");
+ }
+ copyFilesAndTransform(srcDirectory, directory, fileFilter);
+
+ }
+
+ /**
+ *
+ *
+ * copyFiles
+ *
+ *
+ * @param srcDir Source directory to copy from.
+ * @param dstDir Destination directory to copy to.
+ * @throws IOException
+ * @throws FileNotFoundException
+
+ */
+ protected void copyFilesAndTransform(File srcDir, File dstDir, FileFilter fileFilter) throws IOException
+ {
+ FileChannel srcChannel = null;
+ FileChannel dstChannel = null;
+
+ try
+ {
+ File[] children = srcDir.listFiles(fileFilter);
+ for(int i=0; i 0){
+ for (Iterator iter = f.getFragments().iterator(); iter.hasNext();) {
+ Fragment child = (Fragment) iter.next();
+ result.addAll(collectIds(child));
+ }
+ }
+ return result;
+ }
+
+ private int countFragments(Fragment f){
+ int result = 1;
+ for (Iterator iter = f.getFragments().iterator(); iter.hasNext();)
+ {
+ result+=countFragments((Fragment)iter.next());
+ }
+
+ return result;
+ }
+
+ private void compareFolders(Folder folder1, Folder folder2) throws Exception {
+ for (Iterator iter = folder1.getAll().iterator(); iter.hasNext();)
+ {
+ Object obj = iter.next();
+
+ if (obj instanceof Page){
+ Page thisPage = (Page) obj;
+ Page otherPage = folder2.getPage(thisPage.getName());
+ assertEquals(thisPage.getRootFragment()!=null,otherPage.getRootFragment() != null);
+ if (thisPage.getRootFragment() != null){
+ Fragment thisRootFragment = thisPage.getRootFragment();
+ Fragment otherRootFragment = otherPage.getRootFragment();
+ assertEquals(thisRootFragment.getFragments().size(),otherRootFragment.getFragments().size());
+ assertEquals(countFragments(thisRootFragment),countFragments(otherRootFragment));
+ }
+ } else
+ if (obj instanceof Folder){
+ Folder thisFolder = (Folder)obj;
+ compareFolders(thisFolder, folder2.getFolder(thisFolder.getName()));
+ }
+
+ }
+ }
+
+ public void testIdGeneration() throws Exception{
+ Folder webappIds = pageManager.getFolder("/webapp-ids");
+ Folder webappNoIds = pageManager.getFolder("/webapp-no-ids");
+
+ compareFolders(webappIds,webappNoIds);
+
+ Collection allIds = collectIds(webappNoIds);
+ for (Iterator iter = allIds.iterator(); iter.hasNext();) {
+ String id = (String) iter.next();
+ assertNotNull(id);
+ assertEquals(true,id.length() > 0);
+ if (CollectionUtils.cardinality(id, allIds) > 1){
+ System.out.println("Fragment with id "+id+" has duplicates");
+ }
+ assertEquals(1, CollectionUtils.cardinality(id, allIds)); // uniqueness test
+ }
+ }
+
}
Index: components/page-manager/src/test/org/apache/jetspeed/page/PageManagerTestShared.java
===================================================================
--- components/page-manager/src/test/org/apache/jetspeed/page/PageManagerTestShared.java (revision 551254)
+++ components/page-manager/src/test/org/apache/jetspeed/page/PageManagerTestShared.java (working copy)
@@ -27,9 +27,11 @@
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
@@ -69,7 +71,6 @@
import org.apache.jetspeed.security.impl.PrincipalsSet;
import org.apache.jetspeed.security.impl.RolePrincipalImpl;
import org.apache.jetspeed.security.impl.UserPrincipalImpl;
-import org.apache.jetspeed.util.DirectoryHelper;
/**
* PageManagerTestShared
@@ -95,8 +96,13 @@
static CastorXmlPageManager makeCastorXMLPageManager(String pagesDirName, boolean permissionsEnabled, boolean constraintsEnabled)
throws Exception
{
+ Map extensionsToXslt = new HashMap();
+ extensionsToXslt.put("psml","resources/stripIds.xslt");
+
File pagesDirFile = new File("target/testdata/" + pagesDirName);
- DirectoryHelper dirHelper = new DirectoryHelper(pagesDirFile);
+
+
+ DirectoryXMLTransform dirHelper = new DirectoryXMLTransform(pagesDirFile,extensionsToXslt);
FileFilter noCVSorSVNorBackups = new FileFilter()
{
public boolean accept( File pathname )
@@ -105,6 +111,18 @@
}
};
dirHelper.copyFrom(new File("testdata/" + pagesDirName), noCVSorSVNorBackups);
+
+ // copy documents under webapp/pages folder and strip fragment Ids
+ File webappDestDirFile = new File("target/testdata/" + pagesDirName+"/webapp-no-ids");
+ dirHelper.setBaseDirectory(webappDestDirFile);
+ File webappPagesDirFile = new File("../../src/webapp/WEB-INF/pages");
+ dirHelper.copyFromAndTransform(webappPagesDirFile, noCVSorSVNorBackups);
+
+ // copy documents under webapp/pages folder without transforming them
+ webappDestDirFile = new File("target/testdata/" + pagesDirName+"/webapp-ids");
+ dirHelper.setBaseDirectory(webappDestDirFile);
+ dirHelper.copyFrom(webappPagesDirFile, noCVSorSVNorBackups);
+
IdGenerator idGen = new JetspeedIdGenerator(65536,"P-","");
FileCache cache = new FileCache(10, 12);
Index: components/page-manager/src/java/org/apache/jetspeed/om/page/ContentPageImpl.java
===================================================================
--- components/page-manager/src/java/org/apache/jetspeed/om/page/ContentPageImpl.java (revision 551254)
+++ components/page-manager/src/java/org/apache/jetspeed/om/page/ContentPageImpl.java (working copy)
@@ -38,7 +38,8 @@
private final Page page;
private final Map cachedFragments;
private ContentFragment rootContentFragment;
-
+ private boolean dirty=false;
+
public ContentPageImpl(Page page)
{
this.page = page;
@@ -522,4 +523,13 @@
{
page.setVersion(version);
}
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
}
Index: components/page-manager/src/java/org/apache/jetspeed/om/page/psml/DocumentImpl.java
===================================================================
--- components/page-manager/src/java/org/apache/jetspeed/om/page/psml/DocumentImpl.java (revision 551254)
+++ components/page-manager/src/java/org/apache/jetspeed/om/page/psml/DocumentImpl.java (working copy)
@@ -1,9 +1,9 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
@@ -25,18 +25,20 @@
* Link
*
*
- *
+ *
*
+ *
* @author Scott T. Weaver
* @version $Id: LinkImpl.java 314803 2005-10-12 06:35:19Z rwatler $
- *
+ *
*/
public abstract class DocumentImpl extends AbstractNode implements Document
{
private String version;
-
- /**
+ private boolean dirty=false;
+
+ /**
* unmarshalled - notification that this instance has been
* loaded from the persistent store
*/
@@ -65,4 +67,13 @@
{
this.version = version;
}
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
}
Index: components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java
===================================================================
--- components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java (revision 551254)
+++ components/page-manager/src/java/org/apache/jetspeed/om/page/psml/FragmentImpl.java (working copy)
@@ -36,6 +36,8 @@
public class FragmentImpl extends AbstractBaseElement implements Fragment, java.io.Serializable
{
+ private static int fragment_id_counter = 0;
+
private String type = null;
private String state = null;
@@ -60,6 +62,7 @@
private PageImpl page;
+ private boolean dirty = false;
/**
*
* Default Constructor.
@@ -69,6 +72,16 @@
{
}
+ public FragmentImpl(String id)
+ {
+ if (id == null || id.length() == 0){
+ setId(generateId());
+ dirty=true;
+ } else {
+ setId(id);
+ }
+ }
+
public String getType()
{
return this.type;
@@ -468,6 +481,9 @@
{
// set page implementation
this.page = page;
+ if (dirty){
+ page.setDirty(dirty);
+ }
// propagate to children
if (fragments != null)
{
@@ -689,4 +705,8 @@
}
return fragments;
}
+
+ private synchronized static String generateId(){
+ return new StringBuffer("F.").append(Long.toHexString(System.currentTimeMillis())).append(".").append(fragment_id_counter++).toString();
+ }
}
Index: components/page-manager/src/java/org/apache/jetspeed/page/document/impl/DocumentImpl.java
===================================================================
--- components/page-manager/src/java/org/apache/jetspeed/page/document/impl/DocumentImpl.java (revision 551254)
+++ components/page-manager/src/java/org/apache/jetspeed/page/document/impl/DocumentImpl.java (working copy)
@@ -1,9 +1,9 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
@@ -29,6 +29,8 @@
{
private String version;
+ private boolean dirty = false;
+
public DocumentImpl(SecurityConstraintsImpl constraints)
{
super(constraints);
@@ -64,4 +66,13 @@
{
this.version = version;
}
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
}
Index: components/page-manager/src/java/org/apache/jetspeed/page/document/psml/AbstractNode.java
===================================================================
--- components/page-manager/src/java/org/apache/jetspeed/page/document/psml/AbstractNode.java (revision 551254)
+++ components/page-manager/src/java/org/apache/jetspeed/page/document/psml/AbstractNode.java (working copy)
@@ -50,7 +50,8 @@
private String url;
private boolean hidden=false;
private String profiledPath;
-
+ private boolean dirty=false;
+
public AbstractNode()
{
}
@@ -500,4 +501,14 @@
setMetadataFields(metadataFields);
}
}
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty=dirty;
+ }
+
+
}
Index: components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java
===================================================================
--- components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java (revision 551254)
+++ components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java (working copy)
@@ -35,6 +35,7 @@
import org.apache.jetspeed.cache.file.FileCache;
import org.apache.jetspeed.cache.file.FileCacheEntry;
import org.apache.jetspeed.cache.file.FileCacheEventListener;
+import org.apache.jetspeed.om.common.SecurityConstraints;
import org.apache.jetspeed.om.folder.psml.FolderImpl;
import org.apache.jetspeed.om.page.Document;
import org.apache.jetspeed.om.page.psml.AbstractBaseElement;
@@ -49,20 +50,25 @@
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.Serializer;
import org.apache.xml.serialize.XMLSerializer;
+import org.castor.mapping.BindingType;
+import org.castor.mapping.MappingUnmarshaller;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.xml.EventProducer;
+import org.exolab.castor.mapping.MappingLoader;
+import org.exolab.castor.xml.ClassDescriptorResolver;
+import org.exolab.castor.xml.ClassDescriptorResolverFactory;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
+import org.exolab.castor.xml.SAX2EventProducer;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
-import org.xml.sax.AttributeList;
-import org.xml.sax.DocumentHandler;
+import org.exolab.castor.xml.XMLClassDescriptorResolver;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderAdapter;
/**
*
@@ -82,18 +88,16 @@
private final static String PSML_DOCUMENT_ENCODING = "UTF-8";
- protected String mappingFile;
protected String documentType;
protected Class expectedReturnType;
protected String documentRoot;
protected File documentRootDir;
protected FileCache fileCache;
- /** the Castor mapping file name */
- protected Mapping mapping = null;
-
+
private OutputFormat format;
-
+ private final XMLReader xmlReader;
private DocumentHandlerFactory handlerFactory;
+ private ClassDescriptorResolver classDescriptorResolver;
/**
*
@@ -105,10 +109,9 @@
* @throws FileNotFoundException
*/
public CastorFileSystemDocumentHandler( String mappingFile, String documentType, Class expectedReturnType,
- String documentRoot, FileCache fileCache ) throws FileNotFoundException
+ String documentRoot, FileCache fileCache ) throws FileNotFoundException,SAXException,ParserConfigurationException, MappingException
{
super();
- this.mappingFile = mappingFile;
this.documentType = documentType;
this.expectedReturnType = expectedReturnType;
this.documentRoot = documentRoot;
@@ -120,12 +123,22 @@
format.setIndenting(true);
format.setIndent(4);
format.setEncoding(PSML_DOCUMENT_ENCODING);
-
- loadMapping();
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser parser = factory.newSAXParser();
+
+ xmlReader = parser.getXMLReader();
+ xmlReader.setFeature("http://xml.org/sax/features/namespaces", false);
+
+ /*
+ * Create ClassDescripterResolver for better performance.
+ * Mentioned as 'best practice' on the Castor website.
+ */
+ createCastorClassDescriptorResolver(mappingFile);
}
public CastorFileSystemDocumentHandler( String mappingFile, String documentType, String expectedReturnType,
- String documentRoot, FileCache fileCache ) throws FileNotFoundException, ClassNotFoundException
+ String documentRoot, FileCache fileCache ) throws FileNotFoundException, ClassNotFoundException,SAXException,ParserConfigurationException, MappingException
{
this(mappingFile, documentType, Class.forName(expectedReturnType), documentRoot, fileCache);
}
@@ -146,7 +159,12 @@
{
return getDocument(name, true);
}
-
+
+ public void updateDocument( Document document ) throws FailedToUpdateDocumentException
+ {
+ updateDocument(document, false);
+ }
+
/**
*
* updateDocument
@@ -154,8 +172,9 @@
*
* @see org.apache.jetspeed.page.document.DocumentHandler#updateDocument(org.apache.jetspeed.om.page.Document)
* @param document
+ * @param systemUpdate
*/
- public void updateDocument( Document document ) throws FailedToUpdateDocumentException
+ protected void updateDocument( Document document, boolean systemUpdate) throws FailedToUpdateDocumentException
{
// sanity checks
if (document == null)
@@ -176,8 +195,14 @@
}
AbstractBaseElement documentImpl = (AbstractBaseElement)document;
documentImpl.setHandlerFactory(handlerFactory);
- documentImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
- documentImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
+ if (systemUpdate){
+ // on system update: temporarily turn off security
+ documentImpl.setPermissionsEnabled(false);
+ documentImpl.setConstraintsEnabled(false);
+ } else {
+ documentImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
+ documentImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
+ }
documentImpl.marshalling();
// marshal page to disk
@@ -191,17 +216,18 @@
try
{
- // marshal: use SAX I handler to filter document XML for
+ // marshal: use SAX II handler to filter document XML for
// page and folder menu definition menu elements ordered
// polymorphic collection to strip artifical
// tags enabling Castor XML binding; see JETSPEED-INF/castor/page-mapping.xml
writer = new OutputStreamWriter(new FileOutputStream(f), PSML_DOCUMENT_ENCODING);
Serializer serializer = new XMLSerializer(writer, this.format);
- final DocumentHandler handler = serializer.asDocumentHandler();
- Marshaller marshaller = new Marshaller(new DocumentHandler()
+ final ContentHandler handler = serializer.asContentHandler();
+
+ Marshaller marshaller = new Marshaller(new ContentHandler()
{
private int menuDepth = 0;
-
+
public void characters(char[] ch, int start, int length) throws SAXException
{
handler.characters(ch, start, length);
@@ -212,21 +238,6 @@
handler.endDocument();
}
- public void endElement(String name) throws SAXException
- {
- // track menu depth
- if (name.equals("menu"))
- {
- menuDepth--;
- }
-
- // filter menu-element noded within menu definition
- if ((menuDepth == 0) || !name.equals("menu-element"))
- {
- handler.endElement(name);
- }
- }
-
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
handler.ignorableWhitespace(ch, start, length);
@@ -247,22 +258,47 @@
handler.startDocument();
}
- public void startElement(String name, AttributeList atts) throws SAXException
- {
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ // track menu depth
+ if (qName.equals("menu"))
+ {
+ menuDepth--;
+ }
+
// filter menu-element noded within menu definition
- if ((menuDepth == 0) || !name.equals("menu-element"))
+ if ((menuDepth == 0) || !qName.equals("menu-element"))
{
- handler.startElement(name, atts);
+ handler.endElement(uri, localName, qName);
}
+ }
+ 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 {
+ // filter menu-element noded within menu definition
+ if ((menuDepth == 0) || !qName.equals("menu-element"))
+ {
+ handler.startElement(uri,localName, qName, atts);
+ }
+
// track menu depth
- if (name.equals("menu"))
+ if (qName.equals("menu"))
{
menuDepth++;
}
- }
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ }
});
- marshaller.setMapping(this.mapping);
+ marshaller.setResolver((XMLClassDescriptorResolver) classDescriptorResolver);
+
+ marshaller.setValidation(false); // results in better performance
marshaller.marshal(document);
}
catch (MarshalException e)
@@ -270,11 +306,6 @@
log.error("Could not marshal the file " + f.getAbsolutePath(), e);
throw new FailedToUpdateDocumentException(e);
}
- catch (MappingException e)
- {
- log.error("Could not marshal the file " + f.getAbsolutePath(), e);
- throw new FailedToUpdateDocumentException(e);
- }
catch (ValidationException e)
{
log.error("Document " + f.getAbsolutePath() + " is not valid", e);
@@ -292,7 +323,12 @@
}
finally
{
- try
+ if (systemUpdate){
+ // restore permissions / constraints
+ documentImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
+ documentImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
+ }
+ try
{
writer.close();
}
@@ -303,11 +339,10 @@
}
-
-
- protected void loadMapping()
+ protected void createCastorClassDescriptorResolver(String mappingFile) throws MappingException
{
- try
+ Mapping mapping=null;
+ try
{
InputStream stream = getClass().getResourceAsStream(mappingFile);
@@ -329,7 +364,11 @@
ise.initCause(e);
throw ise;
}
-
+ this.classDescriptorResolver =
+ ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
+ MappingUnmarshaller mappingUnmarshaller = new MappingUnmarshaller();
+ MappingLoader mappingLoader = mappingUnmarshaller.getMappingLoader(mapping, BindingType.XML);
+ classDescriptorResolver.setMappingLoader(mappingLoader);
}
protected Object unmarshallDocument( Class clazz, String path, String extension ) throws DocumentNotFoundException,
@@ -353,21 +392,20 @@
try
{
- // unmarshal: use SAX I parser to read document XML, filtering
+ // unmarshal: use SAX II parser to read document XML, filtering
// for page and folder menu definition menu elements ordered
// polymorphic collection to insert artifical
// tags enabling Castor XML binding; see JETSPEED-INF/castor/page-mapping.xml
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser parser = factory.newSAXParser();
- XMLReader reader = parser.getXMLReader();
- final XMLReaderAdapter readerAdapter = new XMLReaderAdapter(reader);
+
final InputSource readerInput = new InputSource(new InputStreamReader(new FileInputStream(f), PSML_DOCUMENT_ENCODING));
- Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
- document = (Document) unmarshaller.unmarshal(new EventProducer()
+ Unmarshaller unmarshaller = new Unmarshaller();
+ unmarshaller.setResolver((XMLClassDescriptorResolver) classDescriptorResolver);
+ unmarshaller.setValidation(false); // results in better performance
+ document = (Document) unmarshaller.unmarshal(new SAX2EventProducer()
{
- public void setDocumentHandler(final DocumentHandler handler)
+ public void setContentHandler(final ContentHandler handler)
{
- readerAdapter.setDocumentHandler(new DocumentHandler()
+ xmlReader.setContentHandler(new ContentHandler()
{
private int menuDepth = 0;
@@ -381,30 +419,6 @@
handler.endDocument();
}
- public void endElement(String name) throws SAXException
- {
- // always include all elements
- handler.endElement(name);
-
- // track menu depth and insert menu-element nodes
- // to encapsulate menu elements to support collection
- // polymorphism in Castor
- if (name.equals("menu"))
- {
- menuDepth--;
- if (menuDepth > 0)
- {
- handler.endElement("menu-element");
- }
- }
- else if ((menuDepth > 0) &&
- (name.equals("options") || name.equals("separator") ||
- name.equals("include") || name.equals("exclude")))
- {
- handler.endElement("menu-element");
- }
- }
-
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
handler.ignorableWhitespace(ch, start, length);
@@ -425,36 +439,68 @@
handler.startDocument();
}
- public void startElement(String name, AttributeList atts) throws SAXException
- {
+ 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 (name.equals("menu"))
+ if (qName.equals("menu"))
{
+ menuDepth--;
if (menuDepth > 0)
{
- handler.startElement("menu-element", null);
+ 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");
+ }
+ }
+
+ 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) &&
- (name.equals("options") || name.equals("separator") ||
- name.equals("include") || name.equals("exclude")))
+ (qName.equals("options") || qName.equals("separator") ||
+ qName.equals("include") || qName.equals("exclude")))
{
- handler.startElement("menu-element", null);
+ handler.startElement(null,null,"menu-element", null);
}
// always include all elements
- handler.startElement(name, atts);
- }
+ handler.startElement(null,null, qName, atts);
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ }
});
}
public void start() throws SAXException
{
try
{
- readerAdapter.parse(readerInput);
+ xmlReader.parse(readerInput);
}
catch (IOException ioe)
{
@@ -469,6 +515,10 @@
documentImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
documentImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
documentImpl.unmarshalled();
+ if (document.isDirty()){
+ updateDocument(document, true);
+ document.setDirty(false);
+ }
}
catch (IOException e)
{
@@ -480,26 +530,11 @@
log.error("Could not unmarshal the file " + f.getAbsolutePath(), e);
throw new PageNotFoundException("Could not unmarshal the file " + f.getAbsolutePath(), e);
}
- catch (MappingException 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);
}
- catch (SAXException e)
- {
- log.error("Could not unmarshal the file " + f.getAbsolutePath(), e);
- throw new PageNotFoundException("Could not unmarshal the file " + f.getAbsolutePath(), e);
- }
- catch (ParserConfigurationException e)
- {
- log.error("Could not unmarshal the file " + f.getAbsolutePath(), e);
- throw new PageNotFoundException("Could not unmarshal the file " + f.getAbsolutePath(), e);
- }
if (document == null)
Index: components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml
===================================================================
--- components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml (revision 551254)
+++ components/page-manager/src/java/JETSPEED-INF/castor/page-mapping.xml (working copy)
@@ -1,5 +1,5 @@
-
1.0
-
- 0.9.4.3
+ 1.1.1-xml
2.1_3
1.7.0
20061115
Index: .classpath
===================================================================
--- .classpath (revision 551254)
+++ .classpath (working copy)
@@ -58,7 +58,7 @@
-
+
@@ -70,6 +70,7 @@
+
Index: core-build.xml
===================================================================
--- core-build.xml (revision 551254)
+++ core-build.xml (working copy)
@@ -246,8 +246,7 @@
castor
-
- 0.9.4.3
+ 1.1.1-xml
true
Index: jetspeed-api/src/java/org/apache/jetspeed/om/page/Document.java
===================================================================
--- jetspeed-api/src/java/org/apache/jetspeed/om/page/Document.java (revision 551254)
+++ jetspeed-api/src/java/org/apache/jetspeed/om/page/Document.java (working copy)
@@ -46,4 +46,27 @@
*/
void setVersion(String versionNumber);
+ /**
+ *
+ * isDirty
+ *
+ *
+ * Whether this node is dirty, i.e. should be updated in the persistent store.
+ *
+ * @param hidden flag
+ */
+ boolean isDirty();
+
+ /**
+ *
+ * setDirty
+ *
+ *
+ * Flag the node as dirty / clean, i.e. should be resp. should not be updated in the persistent store
+ *
+ * @param hidden flag
+ */
+
+ void setDirty(boolean dirty);
+
}
\ No newline at end of file
Index: etc/editors/m2.classpath
===================================================================
--- etc/editors/m2.classpath (revision 551254)
+++ etc/editors/m2.classpath (working copy)
@@ -58,7 +58,7 @@
-
+
Index: etc/editors/2.1.maven2.classpath
===================================================================
--- etc/editors/2.1.maven2.classpath (revision 551254)
+++ etc/editors/2.1.maven2.classpath (working copy)
@@ -58,7 +58,7 @@
-
+