/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/kernel/trunk/kernel-impl/src/main/java/org/sakaiproject/content/impl/serialize/impl/conversion/SAXSerializableCollectionAccess.java $
* $Id: SAXSerializableCollectionAccess.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $
***********************************************************************************
*
* 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.content.impl.serialize.impl.conversion;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.content.api.ResourceType;
import org.sakaiproject.content.api.GroupAwareEntity.AccessMode;
import org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess;
import org.sakaiproject.content.impl.serialize.impl.Type1BaseContentCollectionSerializer;
import org.sakaiproject.entity.api.serialize.SerializableEntity;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.util.StringUtil;
import org.sakaiproject.util.Xml;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* @author ieb
*/
public class SAXSerializableCollectionAccess implements SerializableCollectionAccess,
SerializableEntity
{
protected static final long END_OF_TIME = 8000L * 365L * 24L * 60L * 60L * 1000L;
protected static final long START_OF_TIME = 365L * 24L * 60L * 60L * 1000L;
protected static final Log log = LogFactory
.getLog(SAXSerializableResourceAccess.class);
private Type1BaseContentCollectionSerializer type1CollectionSerializer;
private SAXParserFactory parserFactory;
private AccessMode accessMode = AccessMode.INHERITED;
private Collection<String> group = new ArrayList<String>();
private boolean hidden;
private String id;
private SAXSerializablePropertiesAccess saxSerializableProperties = new SAXSerializablePropertiesAccess();
private Time releaseDate;
private Time retractDate;
private String resourceType;
private ConversionTimeService conversionTimeService;
public SAXSerializableCollectionAccess()
{
type1CollectionSerializer = new Type1BaseContentCollectionSerializer();
conversionTimeService = new ConversionTimeService();
type1CollectionSerializer.setTimeService(conversionTimeService);
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableAccess()
*/
public AccessMode getSerializableAccess()
{
return accessMode;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableGroup()
*/
public Collection<String> getSerializableGroup()
{
return group;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableHidden()
*/
public boolean getSerializableHidden()
{
return hidden;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableId()
*/
public String getSerializableId()
{
return id;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableProperties()
*/
public SerializableEntity getSerializableProperties()
{
return saxSerializableProperties;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableReleaseDate()
*/
public Time getSerializableReleaseDate()
{
return releaseDate;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#getSerializableRetractDate()
*/
public Time getSerializableRetractDate()
{
return retractDate;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableAccess(org.sakaiproject.content.api.GroupAwareEntity.AccessMode)
*/
public void setSerializableAccess(AccessMode access)
{
this.accessMode = access;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableGroups(java.util.Collection)
*/
public void setSerializableGroups(Collection<String> groups)
{
this.group = groups;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableHidden(boolean)
*/
public void setSerializableHidden(boolean hidden)
{
this.hidden = hidden;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableId(java.lang.String)
*/
public void setSerializableId(String id)
{
this.id = id;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableReleaseDate(org.sakaiproject.time.api.Time)
*/
public void setSerializableReleaseDate(Time releaseDate)
{
this.releaseDate = releaseDate;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableResourceType(java.lang.String)
*/
public void setSerializableResourceType(String resourceType)
{
this.resourceType = resourceType;
}
/*
* (non-Javadoc)
*
* @see org.sakaiproject.content.impl.serialize.api.SerializableCollectionAccess#setSerializableRetractDate(org.sakaiproject.time.api.Time)
*/
public void setSerializableRetractDate(Time retractDate)
{
this.retractDate = retractDate;
}
/**
* @param xml
*/
public void parse(String xml) throws Exception
{
Reader r = new StringReader(xml);
InputSource ss = new InputSource(r);
SAXParser p = null;
if (parserFactory == null)
{
parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(false);
parserFactory.setValidating(false);
}
try
{
p = parserFactory.newSAXParser();
}
catch (ParserConfigurationException e)
{
throw new SAXException("Failed to get a parser ", e);
}
final Map<String, Object> props = new HashMap<String, Object>();
saxSerializableProperties.setSerializableProperties(props);
p.parse(ss, new DefaultHandler()
{
/*
* (non-Javadoc)
*
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
* java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
if ("property".equals(qName))
{
String name = attributes.getValue("name");
String enc = StringUtils.trimToNull(attributes.getValue("enc"));
String value = null;
if ("BASE64".equalsIgnoreCase(enc))
{
String charset = StringUtils.trimToNull(attributes
.getValue("charset"));
if (charset == null) charset = "UTF-8";
value = Xml.decode(charset, attributes.getValue("value"));
}
else
{
value = attributes.getValue("value");
}
// deal with multiple valued lists
if ("list".equals(attributes.getValue("list")))
{
// accumulate multiple values in a list
Object current = props.get(name);
// if we don't have a value yet, make a list to
// hold
// this one
if (current == null)
{
List values = new Vector();
props.put(name, values);
values.add(value);
}
// if we do and it's a list, add this one
else if (current instanceof List)
{
((List) current).add(value);
}
// if it's not a list, it's wrong!
else
{
log.warn("construct(el): value set not a list: " + name);
}
}
else
{
props.put(name, value);
}
}
else if ("collection".equals(qName))
{
id = attributes.getValue("id");
resourceType = ResourceType.TYPE_FOLDER;
// extract access
accessMode = AccessMode.INHERITED;
String access_mode = attributes.getValue("sakai:access_mode");
if (access_mode != null && !access_mode.trim().equals(""))
{
accessMode = AccessMode.fromString(access_mode);
}
if (accessMode == null || AccessMode.SITE == accessMode)
{
accessMode = AccessMode.INHERITED;
}
// extract release date
// m_releaseDate = TimeService.newTime(0);
String date0 = attributes.getValue("sakai:release_date");
if (date0 != null && !date0.trim().equals(""))
{
releaseDate = conversionTimeService.newTimeGmt(date0);
if (releaseDate.getTime() <= START_OF_TIME)
{
releaseDate = null;
}
}
// extract retract date
// m_retractDate = TimeService.newTimeGmt(9999,12,
// 31, 23, 59, 59, 999);
String date1 = attributes.getValue("sakai:retract_date");
if (date1 != null && !date1.trim().equals(""))
{
retractDate = conversionTimeService.newTimeGmt(date1);
if (retractDate.getTime() >= END_OF_TIME)
{
retractDate = null;
}
}
String shidden = attributes.getValue("sakai:hidden");
hidden = shidden != null && !shidden.trim().equals("")
&& !Boolean.FALSE.toString().equalsIgnoreCase(shidden);
}
else if ("sakai:authzGroup".equals(qName))
{
String groupRef = attributes.getValue("sakai:group_name");
if (groupRef != null)
{
group.add(groupRef);
}
}
else if ("rightsAssignment".equals(qName))
{
}
else if ("properties".equals(qName))
{
}
else
{
log.warn("Unexpected Element " + qName);
}
}
});
}
/**
* @param sax2
* @throws Exception
*/
public void check(SAXSerializableCollectionAccess sax2) throws Exception
{
StringBuilder sb = new StringBuilder();
if ((accessMode != null && !accessMode.equals(sax2.accessMode))
|| (accessMode == null && sax2.accessMode != null)
|| (accessMode != null && sax2.accessMode == null))
{
sb.append(" ").append(
"Access Mode not equal [" + accessMode + "]!=[" + sax2.accessMode
+ "]").append("\n");
}
if (this.hidden != sax2.hidden)
{
sb.append(" ").append(
"Hidden not equal [" + hidden + "]!=[" + sax2.hidden + "]").append(
"\n");
}
if ((id != null && !id.equals(sax2.id)) || (id == null && sax2.id != null)
|| (id != null && sax2.id == null))
{
sb.append(" ").append("ID not equal [" + id + "]!=[" + sax2.id + "]")
.append("\n");
}
if ((releaseDate != null && sax2.releaseDate != null && (this.releaseDate
.getTime() != sax2.releaseDate.getTime()))
|| (releaseDate == null && sax2.releaseDate != null)
|| (releaseDate != null && sax2.releaseDate == null))
{
sb.append(" ")
.append(
"Release not equal [" + releaseDate + "]!=["
+ sax2.releaseDate + "]").append("\n");
}
if ((retractDate != null && sax2.retractDate != null && (this.retractDate
.getTime() != sax2.retractDate.getTime()))
|| (retractDate == null && sax2.retractDate != null)
|| (retractDate != null && sax2.retractDate == null))
{
sb.append(" ")
.append(
"Release not equal [" + retractDate + "]!=["
+ sax2.retractDate + "]").append("\n");
}
if ((resourceType != null && !resourceType.equals(sax2.resourceType))
|| (resourceType == null && sax2.resourceType != null)
|| (resourceType != null && sax2.resourceType == null))
{
sb.append(" ").append(
"ID not equal [" + resourceType + "]!=[" + sax2.resourceType + "]")
.append("\n");
}
if ((group == null && sax2.group != null)
|| (group != null && sax2.group == null))
{
sb.append(" ").append(
"group not equal [" + group + "]!=[" + sax2.group + "]").append("\n");
}
if (group != null && sax2.group != null)
{
if (this.group.size() != sax2.group.size())
{
sb.append(" ").append(
"group not equal [" + group + "]!=[" + sax2.group + "]").append(
"\n");
}
else
{
for (String g : group)
{
if (!sax2.group.contains(g))
{
sb.append(" ").append(
"group not present in other object [" + g + "]").append(
"\n");
}
}
for (String g : sax2.group)
{
if (!group.contains(g))
{
sb.append(" ").append(
"group not present in this object [" + g + "]").append(
"\n");
}
}
}
}
if (sb.length() != 0)
{
log.error(sb.toString());
throw new Exception("Serialization Items do not match ");
}
}
}