adds package portation to core for ex- and importing of system objects

git-svn-id: https://svn.libreccm.org/ccm/trunk@4060 8810af33-2d31-482b-a856-94f89814c4df
master
tosmers 2016-05-09 12:46:41 +00:00
parent 3376107c4a
commit 9658f75f5d
8 changed files with 425 additions and 9 deletions

View File

@ -36,6 +36,7 @@ import com.arsdigita.persistence.metadata.Property;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.SQLException; import java.sql.SQLException;
import com.arsdigita.portation.AbstractMarshaller;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.log4j.Priority; import org.apache.log4j.Priority;

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.kernel;
import com.arsdigita.portation.AbstractMarshaller;
/**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
* @version created the 5/9/16
*/
public interface Identifiable {
AbstractMarshaller<? extends Identifiable> getMarshaller();
}

View File

@ -0,0 +1,192 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.log4j.Logger;
import com.arsdigita.kernel.Identifiable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract class responsible for ex- and importing entity-objects to several
* file-formats. Every entity-class (e.g. DocRepo.File) needs to have its own
* extension of this class to override the abstract methods, making it
* possible to ex- or import that extending entity-class (e.g. DocRepo
* .FileMarshal).
*
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
* @version created the 2/10/16
*/
public abstract class AbstractMarshaller<I extends Identifiable> {
private static final Logger log = Logger.getLogger(AbstractMarshaller.class);
private Format format;
private String filename;
// XML specifics
ObjectMapper xmlMapper;
// JSON specifics
// CSV specifics
public void prepare(final Format format, String filename, boolean
indentation) {
this.format = format;
this.filename = filename;
switch (this.format) {
case XML:
// for additional configuration
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
xmlMapper = new XmlMapper(module);
if (indentation) {
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
}
break;
case JSON:
break;
case CSV:
break;
default:
break;
}
}
public void exportList(final List<I> exportList) {
File file = new File(filename);
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file);
} catch (IOException e) {
log.error(String.format("Unable to open a fileWriter for the file" +
" with the name %s.", file.getName()));
}
if (fileWriter != null) {
for (I object : exportList) {
String line = null;
switch (format) {
case XML:
try {
line = xmlMapper.writeValueAsString(object);
//log.info(line);
} catch (IOException e) {
log.error(String.format("Unable to write objetct " +
"of class %s as XML string with name %s.",
object.getClass(), file.getName()), e);
}
break;
case JSON:
break;
case CSV:
break;
default:
break;
}
if (line != null) {
try {
fileWriter.write(line);
fileWriter.write(System.getProperty("line.separator"));
} catch (IOException e) {
log.error(String.format("Unable to write to file with the" +
" name %s.", file.getName()));
}
}
}
try {
fileWriter.close();
} catch (IOException e) {
log.error(String.format("Unable to close a fileWriter for the" +
" file with the name %s.", file.getName()));
}
}
}
protected abstract Class<I> getObjectClass();
protected abstract void insertIntoDb(I object);
public List<I> importFile() {
File file = new File(filename);
List<String> lines = null;
try {
lines = Files.readAllLines(file.toPath());
} catch (IOException e) {
log.error(String.format("Unable to read lines of the file with " +
"name %s.", file.getName()));
}
List<I> objects = new ArrayList<I>();
if (lines != null) {
for (String line : lines) {
I object = null;
switch (format) {
case XML:
try {
object = xmlMapper.readValue(line, getObjectClass());
} catch (IOException e) {
log.error(String.format("Unable to read objects " +
"from XML line:\n \"%s\"", line), e);
}
break;
case JSON:
break;
case CSV:
break;
default:
break;
}
assert object != null;
insertIntoDb(object);
objects.add(object);
}
}
return objects;
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation;
/**
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version created the 03.02.2016
*/
public enum Format {
CSV, XML, JSON
}

View File

@ -0,0 +1,167 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.portation;
import com.arsdigita.kernel.Identifiable;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Central class for exporting and importing objects of this system stored in
* the database.
*
* <info>Exporting or importing object classes need to implement
* interface identifiable.</info>
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version created the 03.02.2016
*/
public class Marshaller {
private static final Logger log = Logger.getLogger(Marshaller.class);
// Assigns lists with objects of the same type as values to their typ as
// key.
private Map<Class<? extends Identifiable>, List<Identifiable>> classListMap;
/**
* Main export method. Organizes the objects into list of the same type
* and calls a second export method for each list.
*
* @param objects All objects to be exported
* @param format The export style/format e.g. CSV or JSON
* @param filename The name of the file to be exported to
*/
public void exportObjects(List<Identifiable> objects, Format format,
String filename) {
putObjects(objects);
for (Map.Entry<Class<? extends Identifiable>, List<Identifiable>>
classListEntry : classListMap.entrySet()) {
exportList(classListEntry.getValue(), classListEntry.getKey(),
format, filename);
}
}
/**
* Organizes a list of different {@link Identifiable} objects into a map
* assigning lists of the same type to their type as values to a key. The
* type which all objects of that list have in common is their key.
* That opens the possibility of being certain of the objects types in
* the list. Guarantied through this implementation.
*
* @param objects list of all objects being organized
*/
private void putObjects(List<Identifiable> objects) {
for (Identifiable object : objects) {
Class<? extends Identifiable> type = object.getClass();
if (classListMap.containsKey(type)) {
classListMap.get(type).add(object);
} else {
List<Identifiable> values = new ArrayList<>();
values.add(object);
classListMap.put(type, values);
}
}
}
/**
* Selects the right marshaller for the given type, initializes that
* marshaller for the given export wishes and calls the export method of
* that marshaller upon the given list of same typed objects.
*
* Naming convention for the export file name:
* <basic file name>__<type/class name>.<format>
*
* @param list List of objects to be exported of the same type
* @param type The class of the type
* @param format The export style
* @param filename The filename
* @param <I> The type of the current marshaller
*/
private <I extends Identifiable> void exportList(List<I> list, Class<?
extends I> type, Format format, String filename) {
@SuppressWarnings("unchecked")
AbstractMarshaller<I> marshaller = (AbstractMarshaller<I>) list.get
(0).getMarshaller();
marshaller.prepare(format, filename + "__" + type.toString(),
false);
marshaller.exportList(list);
}
/**
* Selects the right marshaller for each file being imported depending on
* the filename. Therefore the filename has to contain the name of the
* class this file stores objects for. The marshaller will then be
* initialized and be called for importing the objects contained in the
* file being processed.
*
* Naming convention for the import file name:
* <basic file name>__<type/class name>.<format>
*
* @param filenames List of filenames for the files wishing to be imported
* @param format The import style
* @param <I> The type of the current marshaller
*/
public <I extends Identifiable> void importObjects(
List<String> filenames, Format format) {
for (String filename : filenames) {
String[] splitFilename = filename.split("__");
String className =
splitFilename[splitFilename.length].split(".")[0];
try {
Class clazz = Class.forName(className);
@SuppressWarnings("unchecked")
Class<I> type = clazz.asSubclass(Identifiable.class);
I instance = null;
try {
instance = type.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
log.error(String.format("Error finding an instance for " +
"the given type %s.", type.getName()), e);
}
if (instance != null) {
@SuppressWarnings("unchecked")
AbstractMarshaller<I> marshaller = (AbstractMarshaller<I>)
instance.getMarshaller();
marshaller.prepare(format, filename, false);
marshaller.importFile();
} else {
log.error(String.format("Class instance for type %s has " +
"has null value!", type.getName()));
}
} catch (ClassNotFoundException e) {
log.error(String.format("Error finding class for given name: " +
"%s.", className), e);
}
}
}
}

View File

@ -27,12 +27,11 @@ import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.metadata.ObjectType; import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.util.Assert; import com.arsdigita.util.Assert;
import org.apache.log4j.Logger;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Date; import java.util.Date;
import org.apache.log4j.Logger;
// old versioning // old versioning
/** /**

View File

@ -24,11 +24,14 @@ import com.arsdigita.mimetypes.MimeType;
import com.arsdigita.persistence.DataObject; import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.OID; import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.metadata.Property; import com.arsdigita.persistence.metadata.Property;
import com.arsdigita.portation.AbstractMarshaller;
import com.arsdigita.util.Assert; import com.arsdigita.util.Assert;
import org.apache.log4j.Logger;
import org.apache.oro.text.perl.Perl5Util;
import javax.activation.DataHandler; import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.activation.DataSource; import javax.activation.DataSource;
import javax.activation.FileDataSource;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -37,9 +40,6 @@ import java.math.BigDecimal;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import org.apache.log4j.Logger;
import org.apache.oro.text.perl.Perl5Util;
/** /**
* Represents a File in the document manager application. * Represents a File in the document manager application.
* *
@ -47,7 +47,7 @@ import org.apache.oro.text.perl.Perl5Util;
* @author Ron Henderson (ron@arsdigita.com) * @author Ron Henderson (ron@arsdigita.com)
* @version $Id: File.java pboy $ * @version $Id: File.java pboy $
*/ */
public class File extends ResourceImpl { public class File extends ResourceImpl {
/** Logger instance for debugging support. */ /** Logger instance for debugging support. */
protected static Logger s_log = Logger.getLogger(File.class); protected static Logger s_log = Logger.getLogger(File.class);

View File

@ -45,8 +45,8 @@ compile.nowarn=on
# Optionally specifiy version of target JVM. # Optionally specifiy version of target JVM.
# By default the version of the build system is determined and used as target. # By default the version of the build system is determined and used as target.
compile.source=1.6 compile.source=1.8
compile.target=1.6 compile.target=1.8
compile.encoding=UTF-8 compile.encoding=UTF-8
# These properties are specific to Jikes # These properties are specific to Jikes