/*******************************************************************************
* Copyright 2006 - 2012 Vienna University of Technology,
* Department of Software Technology and Interactive Systems, IFS
*
* Licensed 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
*
* 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 eu.scape_project.planning.xml.plan;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import eu.scape_project.planning.model.ByteStream;
import eu.scape_project.planning.model.ChangeLog;
import org.dom4j.Document;
import org.dom4j.io.DOMReader;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.w3c.dom.Element;
/**
* Helper class for {@link eu.scape_project.planning.xml.PlanParser} to read an
* XML element. Can set the decoded data to other objects which have a function
* setData(byte[] data)
*/
public class XMLDataWrapper implements Serializable {
private static final long serialVersionUID = 2080538998419720006L;
/**
* Encoding used for writing data.
*/
private static final String ENCODING = "UTF-8";
/**
* The default output format used for this class.
*/
public static final OutputFormat DEFAULT_OUTPUT_FORMAT;
private OutputFormat outputFormat = DEFAULT_OUTPUT_FORMAT;
private String methodName = "setData";
private String changeLogMethodName = null;
private byte[] data = null;
private ChangeLog changeLog = null;
static {
DEFAULT_OUTPUT_FORMAT = OutputFormat.createPrettyPrint();
DEFAULT_OUTPUT_FORMAT.setEncoding(ENCODING);
}
/**
* Reads an XML element and <code>value</code> and keeps this data for the
* next call of {@link #setData(Object)}.
*
* Additionally checks the <code>value</code> if a <code>changelog</code>
* element is present and stores it for the next call of
* {@link #setChangeLog(Object)}.
*
* @param value
* the value to create
* @throws IOException
* if the data could not be written
* @throws ParseException
* if the data could not be parsed
*/
public void setEncoded(Element value) throws IOException, ParseException {
DOMReader reader = new DOMReader();
org.w3c.dom.Document w3cDocument = value.getOwnerDocument();
w3cDocument.appendChild(value);
Document doc = reader.read(w3cDocument);
org.dom4j.Element changeLogElement = (org.dom4j.Element) doc.selectSingleNode("//*[local-name()='changelog']");
createChangeLog(changeLogElement);
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLWriter writer = new XMLWriter(out, outputFormat);
writer.write(doc);
this.data = out.toByteArray();
}
/**
* Invokes the previously set method <methodName> on <code>object</code> via
* reflection - with previously decoded data as parameter.
*
* @param object
* the object where the data should be set
* @throws NoSuchMethodException
* if the method could not be invoked
* @throws IllegalAccessException
* if the method could not be invoked
* @throws InvocationTargetException
* if the method could not be invoked
*/
public void setData(Object object) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
ByteStream bs = new ByteStream();
bs.setData(data);
Method setDataMethod = object.getClass().getMethod(methodName, ByteStream.class);
setDataMethod.invoke(object, new Object[] {bs});
}
/**
* Invokes the previously set method <methodName> on <code>object</code> via
* reflection - with previously decoded data as parameter.
*
* @param object
* the object where the data should be set
* @throws NoSuchMethodException
* if the method could not be invoked
* @throws IllegalAccessException
* if the method could not be invoked
* @throws InvocationTargetException
* if the method could not be invoked
*/
public void setString(Object object) throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
ByteStream bs = new ByteStream();
bs.setData(data);
Method setDataMethod = object.getClass().getMethod(methodName, String.class);
String dataString = new String(data);
setDataMethod.invoke(object, new Object[] {dataString});
}
/**
* Invokes the previously set method <changeLogMethodName> on
* <code>object</code> via reflection - with previously decoded change log
* data as parameter.
*
* @param object
* the object where the change log should be set
* @throws NoSuchMethodException
* if the method could not be invoked
* @throws IllegalAccessException
* if the method could not be invoked
* @throws InvocationTargetException
* if the method could not be invoked
*/
public void setChangeLog(Object object) throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
Method setData = object.getClass().getMethod(changeLogMethodName, ChangeLog.class);
setData.invoke(object, new Object[] {changeLog});
}
/**
* Creates a change log from the provided changeLogElement.
*
* @param changeLogElement
* the element containing the change log
* @throws ParseException
* if the date could not be parsed
*/
private void createChangeLog(org.dom4j.Element changeLogElement) throws ParseException {
changeLog = new ChangeLog();
if (changeLogElement == null) {
return;
}
TimestampFormatter formatter = new TimestampFormatter();
changeLog.setChangedBy(changeLogElement.attributeValue("changedBy"));
changeLog.setCreatedBy(changeLogElement.attributeValue("createdBy"));
String changed = changeLogElement.attributeValue("changed");
String created = changeLogElement.attributeValue("created");
changeLog.setChanged(formatter.parseTimestamp(changed));
changeLog.setCreated(formatter.parseTimestamp(created));
}
// ---------- getter/setter ----------
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getChangeLogMethodName() {
return changeLogMethodName;
}
public void setChangeLogMethodName(String changeLogMethodName) {
this.changeLogMethodName = changeLogMethodName;
}
public OutputFormat getOutputFormat() {
return outputFormat;
}
public void setOutputFormat(OutputFormat outputFormat) {
this.outputFormat = outputFormat;
}
}