/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/kernel/trunk/kernel-util/src/main/java/org/sakaiproject/util/EntityReaderAdapter.java $
* $Id: EntityReaderAdapter.java 51317 2008-08-24 04:38:02Z csev@umich.edu $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 Sakai Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.util;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.serialize.EntityParseException;
import org.sakaiproject.entity.api.serialize.EntityReaderHandler;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* This class provides a bridge between the XML serializers and the non XML serializers, so that whatever
* the deployed serializer, exisitng Blobs can be read. If this class is configured, it will also
* write the BLOBS out in the new format.
* This class should be used as a Proxy in anything implementing an EntityReader to ensure that other
* formats can still be read.
* @author ieb
*/
public class EntityReaderAdapter implements EntityReaderHandler
{
private static final Log log = LogFactory.getLog(EntityReaderAdapter.class);
private SingleStorageUser storageUser = null;
private String containerEntryTagName;
private String resourceEntryTagName;
private SAXEntityReader saxEntityReader;
private EntityReaderHandler target;
public void init() {
}
public void destroy() {
}
/**
* @throws IOException
* @throws SAXException
* @see org.sakaiproject.entity.api.serialize.EntityReader#parseResource(java.lang.String)
*/
public Entity parse(String xml, byte[] blob) throws EntityParseException
{
if ( target.accept(blob) ) {
return target.parse(xml,blob);
} else {
if (saxEntityReader != null)
{
try
{
DefaultEntityHandler deh = saxEntityReader.getDefaultHandler(saxEntityReader.getServices());
StorageUtils.processString(xml, deh);
return deh.getEntity();
}
catch (Exception ex)
{
throw new EntityParseException("Failed to parse Entity using SAX ",
ex);
}
}
else
{
try
{
// read the xml using DOM.
Document doc = StorageUtils.readDocumentFromString(xml);
// verify the root element
Element root = doc.getDocumentElement();
if (!root.getTagName().equals(containerEntryTagName))
{
log.warn("readContainer(): not = " + containerEntryTagName
+ " : " + root.getTagName());
return null;
}
// re-create a resource
// Originally this code just assumed that it was dealing with a DoubleStorage.
// When the only place it was used was with SingleStorage in which containers don't make
// sense.
Entity entry = null;
if (storageUser instanceof DoubleStorageUser) {
entry = ((DoubleStorageUser)storageUser).newContainer(root);
} else {
entry = storageUser.newResource(null, root);
}
return entry;
}
catch (Exception ex)
{
throw new EntityParseException("Failed to parse Entity using DOM ",
ex);
}
}
}
}
/**
* @throws EntityParseException
* @see org.sakaiproject.entity.api.serialize.EntityReader#parseResource(org.sakaiproject.entity.api.Entity,
* java.lang.String)
*/
public Entity parse(Entity container, String xml, byte[] blob) throws EntityParseException
{
if ( target.accept(blob)) {
log.debug("Parsing Blob "+target);
return target.parse(container,xml,blob);
}
else
{
if (saxEntityReader != null)
{
try
{
log.debug("Parsing With SAX using "+saxEntityReader);
DefaultEntityHandler deh = saxEntityReader.getDefaultHandler(saxEntityReader.getServices());
deh.setContainer(container);
StorageUtils.processString(xml, deh);
return deh.getEntity();
}
catch (Exception ex)
{
throw new EntityParseException("Failed to parse Entity using SAX ",
ex);
}
}
else
{
try
{
// read the xml
Document doc = StorageUtils.readDocumentFromString(xml);
// verify the root element
Element root = doc.getDocumentElement();
if (!root.getTagName().equals(resourceEntryTagName))
{
log.warn("readResource(): not = " + resourceEntryTagName + " : "
+ root.getTagName());
return null;
}
// re-create a resource
Entity entry = storageUser.newResource(container, root);
return entry;
}
catch (Exception ex)
{
throw new EntityParseException("Failed to parse Entity using DOM ",
ex);
}
}
}
}
/**
* @return the containerEntryTagName
*/
public String getContainerEntryTagName()
{
return containerEntryTagName;
}
/**
* @param containerEntryTagName the containerEntryTagName to set
*/
public void setContainerEntryTagName(String containerEntryTagName)
{
this.containerEntryTagName = containerEntryTagName;
}
/**
* @return the resourceEntryTagName
*/
public String getResourceEntryTagName()
{
return resourceEntryTagName;
}
/**
* @param resourceEntryTagName the resourceEntryTagName to set
*/
public void setResourceEntryTagName(String resourceEntryTagName)
{
this.resourceEntryTagName = resourceEntryTagName;
}
/**
* @return the storageUser
*/
public SingleStorageUser getStorageUser()
{
return storageUser;
}
/**
* @param storageUser the storageUser to set
*/
public void setStorageUser(SingleStorageUser storageUser)
{
this.storageUser = storageUser;
}
/**
* We want to always serialise as the target
* @throws EntityParseException
* @see org.sakaiproject.entity.api.serialize.EntityReader#toString(org.sakaiproject.entity.api.Entity)
*/
public byte[] serialize(Entity entry) throws EntityParseException
{
return target.serialize(entry);
}
/**
* Either this or the target will parse whatever is sent to it
* @see org.sakaiproject.entity.api.serialize.EntityReader#accept(java.lang.String)
*/
public boolean accept(byte[] blob)
{
return true;
}
/**
* @return the saxEntityReader
*/
public SAXEntityReader getSaxEntityReader()
{
return saxEntityReader;
}
/**
* @param saxEntityReader the saxEntityReader to set
*/
public void setSaxEntityReader(SAXEntityReader saxEntityReader)
{
this.saxEntityReader = saxEntityReader;
}
/**
* @return the target
*/
public EntityReaderHandler getTarget()
{
return target;
}
/**
* @param target the target to set
*/
public void setTarget(EntityReaderHandler target)
{
this.target = target;
}
}