/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/common/XMLUnmarshaller.java,v 1.16 2001/08/24 20:26:47 dirkv Exp $
* $Revision: 1.16 $
* $Date: 2001/08/24 20:26:47 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.common;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Stack;
import java.util.Date;
import java.io.Reader;
import java.io.Writer;
import org.apache.slide.structure.*;
import org.apache.slide.content.*;
import org.apache.slide.lock.*;
import org.apache.slide.security.*;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.util.conf.Configuration;
import org.apache.slide.util.conf.ConfigurationException;
/**
* XMLUnmarshaller class.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @version $Revision: 1.16 $
*/
public final class XMLUnmarshaller {
// --------------------------------------------------------- Public Methods
/**
* Import data from Avalon configuration object.
*
* @param token CredentialsToken, used for access to the namespace
* @param dataConfiguration Configuration object
* @exception ConfigurationException Something went wrong during the
* reading of the XML
* @exception UnknownObjectClassException Object class not found
* @exception ServiceAccessException Error accessing service
*/
public static void unmarshal(NamespaceAccessToken accessToken,
SlideToken token,
Configuration dataConfiguration)
throws ConfigurationException, UnknownObjectClassException,
ServiceAccessException {
loadObjectNode(accessToken, token,
dataConfiguration.getConfiguration("objectnode"));
}
// -------------------------------------------------------- Private Methods
/**
* Loads a Slide Object.
*
* @param token Credentials token
* @param objectDefinition Configuration object
* @exception ServiceAccessException Object creation failed because
* a data access error occured
* @exception UnknownObjectClassException Object class not found
* @exception ConfigurationException Something went wrong during the
* reading of the XML
*/
private static void loadObjectNode
(NamespaceAccessToken accessToken, SlideToken token,
Configuration objectDefinition)
throws ServiceAccessException, ConfigurationException,
UnknownObjectClassException {
String className = objectDefinition.getAttribute("classname");
String uri = objectDefinition.getAttribute("uri");
Domain.info("Loading object " + uri);
try {
Class objectClass = null;
try {
// First, load the object's class
objectClass = Class.forName(className);
} catch (ClassNotFoundException e) {
// Class loading failed : The requested class was not found
// We throw an exception and interrupt the loading of the file.
throw new UnknownObjectClassException(className);
}
ObjectNode object = null;
try {
// Get a new instance of the class
object = (ObjectNode) objectClass.newInstance();
} catch(InstantiationException e) {
// Instantiation failed for some reason
throw new UnknownObjectClassException(className);
} catch(IllegalAccessException e) {
// The initializer could not be called because
// of access restrictions
throw new UnknownObjectClassException(className);
}
if (uri.equals("/")) {
// FIXME
} else {
try {
if (object instanceof LinkNode) {
String linkedUri =
objectDefinition.getAttribute("linkedUri");
accessToken.getStructureHelper().createLink
(token, (LinkNode) object, uri,
new SubjectNode(linkedUri));
} else {
accessToken.getStructureHelper().create
(token, object, uri);
}
} catch (ObjectAlreadyExistsException e) {
// Ignore, log and continue
Domain.info("Object already exists at " + uri);
}
}
// Retrieving the list of permissions on the object
Enumeration permissionDefinitions =
objectDefinition.getConfigurations("permission");
// We've made sure that the object exists.
// We now parse the permissions definition list, adding each
// permission to the object's permission list.
while (permissionDefinitions.hasMoreElements()) {
Configuration permissionDefinition =
(Configuration) permissionDefinitions.nextElement();
// Create the NodePermission object matching the Castor object
String subjectUri =
permissionDefinition.getAttribute("subject");
String actionUri =
permissionDefinition.getAttribute("action");
boolean inheritable = true;
try {
if (permissionDefinition.getAttribute("inheritable")
.equals("false")) {
inheritable = false;
}
} catch (ConfigurationException e) {
}
boolean negative = false;
try {
if (permissionDefinition.getAttribute("negative")
.equals("true")) {
negative = true;
}
} catch (ConfigurationException e) {
}
NodePermission permission = new NodePermission
(uri, subjectUri, actionUri, inheritable, negative);
// Adding the NodePermission to the ObjectNode
accessToken.getSecurityHelper()
.grantPermission(token, permission);
}
// Retrieve the list of revisions of the object
Enumeration revisionDefinitions =
objectDefinition.getConfigurations("revision");
// We parse the revision definition list
while (revisionDefinitions.hasMoreElements()) {
Configuration revisionDefinition =
(Configuration) revisionDefinitions.nextElement();
loadObjectRevision(accessToken, token, uri,
revisionDefinition);
}
} catch (ObjectNotFoundException e) {
// Should NEVER happen
e.printStackTrace();
Domain.warn(e.getMessage());
} catch (LinkedObjectNotFoundException e) {
// Icorrect link
e.printStackTrace();
Domain.warn("Incorrect link found while creating " + uri);
} catch (AccessDeniedException e) {
// Security exception
Domain.info("Insufficient credentials to create object");
}
Enumeration childConfigurations =
objectDefinition.getConfigurations("objectnode");
while(childConfigurations.hasMoreElements()) {
Configuration childConfiguration =
(Configuration) childConfigurations.nextElement();
loadObjectNode(accessToken, token, childConfiguration);
}
}
/**
* Create the SlideProperties object associated with a ObjectNode.
*
* @param slideObject ObjectNode
* @param propertiesDef Castor object describing the properties associated
* with the ObjectNode
* @exception SlideException A data access error occured
*/
private static void loadObjectRevision(NamespaceAccessToken accessToken,
SlideToken token, String uri,
Configuration revisionDefinition)
throws ServiceAccessException, ConfigurationException,
AccessDeniedException, ObjectNotFoundException,
LinkedObjectNotFoundException {
// Retrieving the list of properties
Enumeration propertyDefinitions =
revisionDefinition.getConfigurations("property");
// Retrieving the revision number, if any
NodeRevisionNumber revisionNumber = null;
// Now creating the new revision descriptor object
NodeRevisionDescriptor revisionDescriptor = null;
NodeRevisionDescriptors revisionDescriptors = null;
try {
revisionDescriptors = accessToken.getContentHelper().retrieve(token, uri);
} catch (ObjectLockedException e) {
// Ignore
}
if ((revisionDescriptors != null)
&& (revisionDescriptors.hasRevisions())) {
try {
revisionDescriptor = accessToken.getContentHelper().retrieve
(token, revisionDescriptors);
} catch (RevisionDescriptorNotFoundException e) {
// Ignore
} catch (ObjectLockedException e) {
// Ignore
}
}
if (revisionDescriptor == null) {
revisionDescriptor = new NodeRevisionDescriptor(0);
}
while (propertyDefinitions.hasMoreElements()) {
Configuration propertyDefinition =
(Configuration) propertyDefinitions.nextElement();
String propertyName = propertyDefinition.getAttribute("name");
String propertyValue = propertyDefinition.getValue();
String propertyNamespace = propertyDefinition.getAttribute
("namespace", NodeProperty.DEFAULT_NAMESPACE);
NodeProperty property = revisionDescriptor.getProperty
(propertyName, propertyNamespace);
if (property == null)
revisionDescriptor.setProperty(propertyName, propertyNamespace,
propertyValue);
}
NodeRevisionContent revisionContent = null;
if ((revisionDescriptors != null)
&& (revisionDescriptors.hasRevisions())) {
try {
revisionContent = accessToken.getContentHelper()
.retrieve(token, uri, revisionDescriptor);
} catch (RevisionContentNotFoundException e) {
// Ignore
} catch (ObjectLockedException e) {
// Ignore
} catch (RevisionNotFoundException e) {
// Should not happen
e.printStackTrace();
Domain.warn(e.getMessage());
}
try {
accessToken.getContentHelper().store
(token, uri, revisionDescriptor, revisionContent);
} catch (RevisionDescriptorNotFoundException e) {
// Should not happen
e.printStackTrace();
Domain.warn(e.getMessage());
} catch (RevisionNotFoundException e) {
// Should not happen
e.printStackTrace();
Domain.warn(e.getMessage());
} catch (ObjectLockedException e) {
// Ignore
}
} else {
try {
accessToken.getContentHelper().create
(token, uri, revisionDescriptor, revisionContent);
} catch(ObjectLockedException e) {
// Should not happen
e.printStackTrace();
Domain.warn(e.getMessage());
} catch(RevisionAlreadyExistException e) {
// Should not happen
e.printStackTrace();
Domain.warn(e.getMessage());
}
}
}
}