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-94f89814c4dfmaster
parent
3376107c4a
commit
9658f75f5d
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue