Central Marhsaller implementation for the exportation is donesvn update
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3913 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
8b941d3e70
commit
dbd7af3c4d
|
|
@ -18,13 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.portation;
|
package org.libreccm.portation;
|
||||||
|
|
||||||
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
|
||||||
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.libreccm.core.Identifiable;
|
import org.libreccm.core.Identifiable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,33 +34,30 @@ import java.util.List;
|
||||||
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
|
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
|
||||||
* @version created the 2/10/16
|
* @version created the 2/10/16
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractMarshaller<T extends Identifiable> {
|
public abstract class AbstractMarshaller<I extends Identifiable> {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(AbstractMarshaller.class);
|
private static final Logger log = Logger.getLogger(AbstractMarshaller.class);
|
||||||
|
|
||||||
|
private Format format;
|
||||||
|
|
||||||
private File exportFile;
|
private File exportFile;
|
||||||
private List<File> importFiles;
|
private List<File> importFiles;
|
||||||
|
|
||||||
private Format format;
|
|
||||||
|
|
||||||
// CSV specifics
|
// CSV specifics
|
||||||
private CsvMapper mapper;
|
|
||||||
private CsvSchema schema;
|
|
||||||
|
|
||||||
// JSON specifics
|
// JSON specifics
|
||||||
|
|
||||||
|
|
||||||
// XML specifics
|
// XML specifics
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param format
|
||||||
|
*/
|
||||||
private void init(final Format format) {
|
private void init(final Format format) {
|
||||||
this.format = format;
|
this.format = format;
|
||||||
|
|
||||||
switch (this.format) {
|
switch (this.format) {
|
||||||
case CSV:
|
case CSV:
|
||||||
mapper = new CsvMapper();
|
|
||||||
schema = getCsvSchema();
|
|
||||||
schema = mapper.schemaFor(getClassT());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSON:
|
case JSON:
|
||||||
|
|
@ -88,30 +82,13 @@ public abstract class AbstractMarshaller<T extends Identifiable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* CSV Export/Import */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main export method. Exports a list of same typed objects to CSV
|
|
||||||
* strings and writes them into the same file with a name specific to
|
|
||||||
* their class.
|
|
||||||
*
|
|
||||||
* TODO: throw exception for ui
|
|
||||||
* TODO: error message not with uuid
|
|
||||||
*
|
*
|
||||||
* @param exportObjects List of {@code T}-tpyed objects being exported
|
* @param exportObjects List of {@code T}-tpyed objects being exported
|
||||||
*/
|
*/
|
||||||
public void exportEntities(final List<T> exportObjects) {
|
public void exportEntities(final List<I> exportObjects) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case CSV:
|
case CSV:
|
||||||
exportObjects.forEach(t -> {
|
|
||||||
try {
|
|
||||||
mapper.writer(schema).writeValue(exportFile, t);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(String.format("Error writing object with UUID " +
|
|
||||||
"%d to CSV-file with the name %s.",
|
|
||||||
1234, exportFile.getName()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSON:
|
case JSON:
|
||||||
|
|
@ -127,27 +104,12 @@ public abstract class AbstractMarshaller<T extends Identifiable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main import method. Imports a list of string representing object of
|
|
||||||
* the same type ({@code T}) from a CSV-file and parses them into the
|
|
||||||
* corresponding objects.
|
|
||||||
*
|
|
||||||
* TODO: throw exception for ui
|
|
||||||
* TODO: error message not with uuid
|
|
||||||
*
|
*
|
||||||
* @return List of {@code T}-typed objects being imported
|
* @return List of {@code T}-typed objects being imported
|
||||||
*/
|
*/
|
||||||
public List<T> importEntities() {
|
public List<I> importEntities() {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case CSV:
|
case CSV:
|
||||||
/*List<T> importObjects = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
mapper.readerFor(getClassT()).with(schema).readValues(file)
|
|
||||||
.forEachRemaining(t -> importObjects.add((T) t));
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error(String.format("Error reading object with UUID %d from " +
|
|
||||||
"CSV-file with the name %s.", 1234, file.getName()));
|
|
||||||
}
|
|
||||||
return importObjects;*/
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSON:
|
case JSON:
|
||||||
|
|
@ -162,29 +124,4 @@ public abstract class AbstractMarshaller<T extends Identifiable> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract method to get the class of the extending subclass fulfilling
|
|
||||||
* the generic type {@code T}.
|
|
||||||
*
|
|
||||||
* @return Class of the extending subclass.
|
|
||||||
*/
|
|
||||||
protected abstract Class getClassT();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract method to get the CSV schema needed for both ex- and
|
|
||||||
* importation specific to every extending subclass.
|
|
||||||
*
|
|
||||||
* @return The CSV schema specific to the implementing subclass
|
|
||||||
*/
|
|
||||||
protected abstract CsvSchema getCsvSchema();
|
|
||||||
|
|
||||||
|
|
||||||
/* JSON Export/Import */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* XML Export/Import */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,15 @@ import javax.faces.bean.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Central class for exporting and importing objects of this system stored in
|
||||||
|
* the database. Retrieves all available implementations of
|
||||||
|
* {@link AbstractMarshaller} using CDI. The implementations have to be CDI
|
||||||
|
* beans of course. Also they must be annotated with the {@link Marshals}
|
||||||
|
* annotation.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
|
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
|
||||||
* @version created the 03.02.2016
|
* @version created the 03.02.2016
|
||||||
|
|
@ -45,72 +48,95 @@ public class Marshaller {
|
||||||
private Instance<AbstractMarshaller<? extends Identifiable>>
|
private Instance<AbstractMarshaller<? extends Identifiable>>
|
||||||
marshallerInstances;
|
marshallerInstances;
|
||||||
|
|
||||||
|
// 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
|
* @param objects All objects to be exported
|
||||||
* @param format
|
* @param format The export style/format e.g. CSV or JSON
|
||||||
* @param filename
|
* @param filename The name of the file to be exported to
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public void exportObjects(List<Identifiable> objects, Format format,
|
||||||
public void exportObjects(List<? extends
|
String filename) {
|
||||||
Identifiable> objects, Format format, String filename) {
|
putObjects(objects);
|
||||||
|
|
||||||
List<List<? extends Identifiable>> objectsByClass = new ArrayList<>();
|
for (Map.Entry<Class<? extends Identifiable>, List<Identifiable>>
|
||||||
Queue<Class<? extends Identifiable>> queue = new LinkedList<>();
|
classListEntry : classListMap.entrySet()) {
|
||||||
|
exportList( classListEntry.getValue(), classListEntry.getKey(),
|
||||||
// Splits list of all entities into lists of the same entity class
|
format, filename);
|
||||||
while (!objects.isEmpty()) {
|
}
|
||||||
Class<? extends Identifiable> clazz = objects.get(0).getClass();
|
|
||||||
objectsByClass.add(objects.stream()
|
|
||||||
.filter(t -> t.getClass() == clazz)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
queue.add(clazz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exports list of the same class
|
/**
|
||||||
for (List objectList : objectsByClass) {
|
* 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.
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
private <I extends Identifiable> void exportList(List<I> list, Class<?
|
||||||
|
extends I> type, Format format, String filename) {
|
||||||
|
|
||||||
final Instance<AbstractMarshaller<? extends Identifiable>>
|
final Instance<AbstractMarshaller<? extends Identifiable>>
|
||||||
marshallerInstance = marshallerInstances.select(new
|
marshallerInstance = marshallerInstances.select(new
|
||||||
MarshalsLiteral(queue.peek()));
|
MarshalsLiteral(type));
|
||||||
|
|
||||||
if (marshallerInstance.isUnsatisfied()) {
|
if (marshallerInstance.isUnsatisfied()) {
|
||||||
// If there are no marshals we have a problem...
|
//If there are no marshallers we have a problem...
|
||||||
throw new IllegalArgumentException(String.format("No " +
|
throw new IllegalArgumentException(String.format(
|
||||||
"marshaller for \"%s\" found.", queue.peek()
|
"No marshallers for \"%s\" found.", type.getName()));
|
||||||
.getName()));
|
|
||||||
} else if (marshallerInstance.isAmbiguous()) {
|
} else if (marshallerInstance.isAmbiguous()) {
|
||||||
// If there is more than one marshaller something is wrong...
|
//If there is more than one marshaller something is wrong...
|
||||||
throw new IllegalArgumentException(String.format("More than " +
|
throw new IllegalArgumentException(String.format(
|
||||||
"one marshaller for \"%s\" found.", queue.peek()
|
"More than one marshaller for \"%s\" found.", type
|
||||||
.getName()));
|
.getName()));
|
||||||
} else {
|
} else {
|
||||||
// Gets the marshaller and calls the export method
|
// Get the marshaller for this list and call the export method.
|
||||||
final Iterator<AbstractMarshaller<? extends Identifiable>> it =
|
final Iterator<AbstractMarshaller<? extends Identifiable>>
|
||||||
marshallerInstance.iterator();
|
iterator = marshallerInstance.iterator();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final AbstractMarshaller<I> marshaller = (AbstractMarshaller<I>)
|
||||||
|
iterator.next();
|
||||||
|
|
||||||
AbstractMarshaller<? extends Identifiable> marshaller = it
|
|
||||||
.next();
|
|
||||||
marshaller.init(format, filename);
|
marshaller.init(format, filename);
|
||||||
marshaller.exportEntities(objectList);
|
marshaller.exportEntities(list);
|
||||||
}
|
|
||||||
queue.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Identifiable> List<T> getListForClass(List<? extends
|
|
||||||
Identifiable> objList, Class<T> objClass) {
|
|
||||||
|
|
||||||
return null;
|
|
||||||
//objList.stream().filter(obj -> obj.getClass() == objClass)
|
|
||||||
// .collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* {@link AnnotationLiteral} used for filtering the available marshallers.
|
||||||
*/
|
*/
|
||||||
private class MarshalsLiteral extends AnnotationLiteral<Marshals>
|
private class MarshalsLiteral extends AnnotationLiteral<Marshals>
|
||||||
implements Marshals {
|
implements Marshals {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Qualifier annotation for implementations of {@link AbstractMarshaller}. The
|
||||||
|
* value is the implementation of {@link Identifiable} for which the annotated
|
||||||
|
* {@link AbstractMarshaller} implementation exports and imports its instances.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
|
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
|
||||||
* @version created the 2/24/16
|
* @version created the 2/24/16
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.docrepo;
|
package org.libreccm.docrepo;
|
||||||
|
|
||||||
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
|
|
||||||
import org.libreccm.portation.AbstractMarshaller;
|
import org.libreccm.portation.AbstractMarshaller;
|
||||||
import org.libreccm.portation.Marshals;
|
import org.libreccm.portation.Marshals;
|
||||||
|
|
||||||
|
|
@ -29,31 +28,4 @@ import org.libreccm.portation.Marshals;
|
||||||
@Marshals(AbstractResource.class)
|
@Marshals(AbstractResource.class)
|
||||||
public class AbstractResourceMarshaller extends AbstractMarshaller<AbstractResource> {
|
public class AbstractResourceMarshaller extends AbstractMarshaller<AbstractResource> {
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class getClassT() {
|
|
||||||
return AbstractResource.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CsvSchema getCsvSchema() {
|
|
||||||
return CsvSchema.builder()
|
|
||||||
.addColumn("object_ID", CsvSchema.ColumnType.NUMBER)
|
|
||||||
.addColumn("displayName")
|
|
||||||
.addColumn("permissions", CsvSchema.ColumnType.ARRAY)
|
|
||||||
.addColumn("categories", CsvSchema.ColumnType.ARRAY)
|
|
||||||
.addColumn("name")
|
|
||||||
.addColumn("description")
|
|
||||||
.addColumn("path")
|
|
||||||
.addColumn("mimeType")
|
|
||||||
.addColumn("size", CsvSchema.ColumnType.NUMBER)
|
|
||||||
.addColumn("creationDate", CsvSchema.ColumnType.NUMBER)
|
|
||||||
.addColumn("lastModifiedDate", CsvSchema.ColumnType.NUMBER)
|
|
||||||
.addColumn("creationIp")
|
|
||||||
.addColumn("lastModifiedIp")
|
|
||||||
.addColumn("creationUser")
|
|
||||||
.addColumn("lastModifiedUser")
|
|
||||||
.addColumn("parent")
|
|
||||||
.addColumn("repository")
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue