[New] Refactored XML import and export model
- added allowInclude for recursive parsing of xml importing - ModelStatistics is now JAXB capable - added handling of absolute paths
This commit is contained in:
parent
c0b9ac930e
commit
a832b2dc3e
|
@ -115,7 +115,7 @@ public class TransientRealm extends InternalStrolchRealm {
|
|||
ModelStatistics statistics;
|
||||
try (StrolchTransaction tx = openTx(privilegeContext.getCertificate(), DefaultRealmHandler.AGENT_BOOT)) {
|
||||
InMemoryElementListener elementListener = new InMemoryElementListener(tx);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(elementListener, this.modelFile);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(elementListener, this.modelFile, true);
|
||||
handler.parseFile();
|
||||
statistics = handler.getStatistics();
|
||||
tx.commitOnClose();
|
||||
|
|
|
@ -4,14 +4,34 @@ import static ch.eitchnet.utils.helper.StringHelper.NULL;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import li.strolch.model.xml.Iso8601DateAdapter;
|
||||
import ch.eitchnet.utils.helper.StringHelper;
|
||||
import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
@XmlRootElement(name = "ModelStatistics")
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class ModelStatistics {
|
||||
|
||||
@XmlAttribute(name = "startTime")
|
||||
@XmlJavaTypeAdapter(value = Iso8601DateAdapter.class)
|
||||
public Date startTime;
|
||||
|
||||
@XmlAttribute(name = "duractionNanos")
|
||||
public long durationNanos;
|
||||
|
||||
@XmlAttribute(name = "nrOfResources")
|
||||
public long nrOfResources;
|
||||
|
||||
@XmlAttribute(name = "nrOfOrders")
|
||||
public long nrOfOrders;
|
||||
|
||||
/**
|
||||
|
@ -28,6 +48,9 @@ public class ModelStatistics {
|
|||
return this.nrOfResources;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nrOfResources + nrOfOrders
|
||||
*/
|
||||
public long getNrOfElements() {
|
||||
return this.nrOfOrders + this.nrOfResources;
|
||||
}
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
package li.strolch.model.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
|
@ -34,19 +32,21 @@ import ch.eitchnet.utils.helper.StringHelper;
|
|||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
*/
|
||||
public class XmlModelSaxFileReader extends XmlModelSaxReader {
|
||||
|
||||
private File modelFile;
|
||||
private boolean allowInclude;
|
||||
|
||||
/**
|
||||
* @param listener
|
||||
* @param modelFile
|
||||
* @param allowInclude
|
||||
*/
|
||||
public XmlModelSaxFileReader(StrolchElementListener listener, File modelFile) {
|
||||
public XmlModelSaxFileReader(StrolchElementListener listener, File modelFile, boolean allowInclude) {
|
||||
super(listener);
|
||||
this.modelFile = modelFile;
|
||||
this.allowInclude = allowInclude;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,11 +56,17 @@ public class XmlModelSaxFileReader extends XmlModelSaxReader {
|
|||
|
||||
case Tags.INCLUDE_FILE:
|
||||
|
||||
if (!this.allowInclude) {
|
||||
String msg = "ModelFile {0} has includes which are disabled for this parse invocation!";
|
||||
throw new IllegalArgumentException(MessageFormat.format(msg, this.modelFile.getAbsolutePath())); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
String includeFileS = attributes.getValue(Tags.FILE);
|
||||
if (StringHelper.isEmpty(includeFileS)) {
|
||||
throw new IllegalArgumentException(MessageFormat.format(
|
||||
"The attribute {0} is missing for IncludeFile!", Tags.FILE)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
File includeFile = new File(this.modelFile.getParentFile(), includeFileS);
|
||||
if (!includeFile.exists() || !includeFile.canRead()) {
|
||||
String msg = "The IncludeFile does not exist, or is not readable. Source model: {0} with IncludeFile: {1}"; //$NON-NLS-1$
|
||||
|
@ -68,7 +74,7 @@ public class XmlModelSaxFileReader extends XmlModelSaxReader {
|
|||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(this.listener, includeFile);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(this.listener, includeFile, this.allowInclude);
|
||||
handler.parseFile();
|
||||
this.statistics.nrOfOrders += handler.statistics.nrOfOrders;
|
||||
this.statistics.nrOfResources += handler.statistics.nrOfResources;
|
||||
|
@ -96,10 +102,10 @@ public class XmlModelSaxFileReader extends XmlModelSaxReader {
|
|||
logger.info(MessageFormat.format(msg, this.modelFile.getAbsolutePath(),
|
||||
StringHelper.formatNanoDuration(this.statistics.durationNanos)));
|
||||
|
||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||
} catch (Exception e) {
|
||||
|
||||
String msg = "Parsing failed due to internal error: {0}"; //$NON-NLS-1$
|
||||
throw new StrolchException(MessageFormat.format(msg, e.getMessage()), e);
|
||||
String msg = "Parsing of {0} failed due to internal error: {1}"; //$NON-NLS-1$
|
||||
throw new StrolchException(MessageFormat.format(msg, this.modelFile.getAbsolutePath(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class XmlModelDefaultHandlerTest {
|
|||
orderMap.put(order.getId(), order);
|
||||
}
|
||||
};
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(listener, file);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(listener, file, true);
|
||||
handler.parseFile();
|
||||
|
||||
assertEquals(3, resourceMap.size());
|
||||
|
|
|
@ -80,7 +80,7 @@ public abstract class PostgreSqlInitializer implements SystemUserAction {
|
|||
File dataStoreF = getDataStoreFile(this.runtimeConfig, this.realmConfig, realmName);
|
||||
|
||||
StoreToDaoElementListener listener = new StoreToDaoElementListener(tx);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(listener, dataStoreF);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(listener, dataStoreF, true);
|
||||
handler.parseFile();
|
||||
statistics = handler.getStatistics();
|
||||
tx.commitOnClose();
|
||||
|
|
|
@ -42,6 +42,7 @@ public class XmlImportModelCommand extends Command {
|
|||
|
||||
// output
|
||||
private ModelStatistics statistics;
|
||||
private boolean allowInclude;
|
||||
|
||||
/**
|
||||
* @param container
|
||||
|
@ -68,7 +69,7 @@ public class XmlImportModelCommand extends Command {
|
|||
elementListener.setOrderTypes(this.orderTypes);
|
||||
elementListener.setResourceTypes(this.resourceTypes);
|
||||
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(elementListener, this.modelFile);
|
||||
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(elementListener, this.modelFile, this.allowInclude);
|
||||
handler.parseFile();
|
||||
|
||||
this.statistics = handler.getStatistics();
|
||||
|
@ -86,6 +87,13 @@ public class XmlImportModelCommand extends Command {
|
|||
this.modelFile = modelFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowInclude
|
||||
*/
|
||||
public void setAllowInclude(boolean allowInclude) {
|
||||
this.allowInclude = allowInclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param addOrders
|
||||
* the addOrders to set
|
||||
|
|
|
@ -40,7 +40,7 @@ public class XmlExportModelArgument extends ServiceArgument {
|
|||
builder.append("external=");
|
||||
builder.append(this.external);
|
||||
|
||||
builder.append("modelFileName=");
|
||||
builder.append(", modelFileName=");
|
||||
builder.append(this.modelFileName);
|
||||
|
||||
builder.append(", overwrite=");
|
||||
|
|
|
@ -24,10 +24,53 @@ public class XmlImportModelArgument extends ServiceArgument {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public String modelFileName;
|
||||
public boolean external = false;
|
||||
public boolean allowInclude = true;
|
||||
public boolean addOrders = true;
|
||||
public boolean addResources = true;
|
||||
public boolean updateOrders = true;
|
||||
public boolean updateResources = true;
|
||||
public Set<String> orderTypes = new HashSet<>();
|
||||
public Set<String> resourceTypes = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("XmlImportModelArgument [ ");
|
||||
|
||||
builder.append("external=");
|
||||
builder.append(this.external);
|
||||
|
||||
builder.append(", allowInclude=");
|
||||
builder.append(this.allowInclude);
|
||||
|
||||
builder.append(", modelFileName=");
|
||||
builder.append(this.modelFileName);
|
||||
|
||||
if (this.addOrders)
|
||||
builder.append(", addOrders");
|
||||
if (this.addResources)
|
||||
builder.append(", addResources");
|
||||
|
||||
if (this.updateOrders)
|
||||
builder.append(", updateOrders");
|
||||
if (this.updateResources)
|
||||
builder.append(", updateResources");
|
||||
|
||||
if (this.resourceTypes != null && !this.resourceTypes.isEmpty()) {
|
||||
builder.append(", resourceTypes=");
|
||||
builder.append(this.resourceTypes);
|
||||
} else {
|
||||
builder.append(", resourceTypes=*");
|
||||
}
|
||||
if (this.orderTypes != null && !this.orderTypes.isEmpty()) {
|
||||
builder.append(", orderTypes=");
|
||||
builder.append(this.orderTypes);
|
||||
} else {
|
||||
builder.append(", orderTypes=*");
|
||||
}
|
||||
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -23,30 +23,49 @@ import li.strolch.exception.StrolchException;
|
|||
import li.strolch.model.ModelStatistics;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.service.api.AbstractService;
|
||||
import li.strolch.service.api.ServiceResult;
|
||||
import li.strolch.service.api.ServiceResultState;
|
||||
import ch.eitchnet.utils.helper.StringHelper;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class XmlImportModelService extends AbstractService<XmlImportModelArgument, ServiceResult> {
|
||||
public class XmlImportModelService extends AbstractService<XmlImportModelArgument, XmlImportModelResult> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected ServiceResult getResultInstance() {
|
||||
return new ServiceResult();
|
||||
protected XmlImportModelResult getResultInstance() {
|
||||
return new XmlImportModelResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceResult internalDoService(XmlImportModelArgument arg) {
|
||||
protected XmlImportModelResult internalDoService(XmlImportModelArgument arg) {
|
||||
|
||||
File dataPath = getRuntimeConfiguration().getDataPath();
|
||||
File modelFile = new File(dataPath, arg.modelFileName);
|
||||
if (!modelFile.exists()) {
|
||||
String msg = "Model File does not exist with name {0} in data path {1}"; //$NON-NLS-1$
|
||||
msg = MessageFormat.format(msg, arg.modelFileName, dataPath);
|
||||
throw new StrolchException(msg);
|
||||
File modelFile;
|
||||
File modelFileName = new File(arg.modelFileName);
|
||||
if (modelFileName.isAbsolute()) {
|
||||
if (!arg.external) {
|
||||
return new XmlImportModelResult(ServiceResultState.FAILED,
|
||||
"Model file is absolute, yet service argument is not marked as external!");
|
||||
}
|
||||
|
||||
modelFile = modelFileName;
|
||||
|
||||
if (!modelFile.exists()) {
|
||||
String msg = "Model File does not exist at {0}"; //$NON-NLS-1$
|
||||
msg = MessageFormat.format(msg, modelFile.getAbsolutePath());
|
||||
throw new StrolchException(msg);
|
||||
}
|
||||
|
||||
} else {
|
||||
File dataPath = getRuntimeConfiguration().getDataPath();
|
||||
modelFile = new File(dataPath, arg.modelFileName);
|
||||
|
||||
if (!modelFile.exists()) {
|
||||
String msg = "Model File does not exist with name {0} in data path {1}"; //$NON-NLS-1$
|
||||
msg = MessageFormat.format(msg, arg.modelFileName, dataPath);
|
||||
throw new StrolchException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
XmlImportModelCommand command;
|
||||
|
@ -54,6 +73,7 @@ public class XmlImportModelService extends AbstractService<XmlImportModelArgumen
|
|||
|
||||
command = new XmlImportModelCommand(getContainer(), tx);
|
||||
command.setModelFile(modelFile);
|
||||
command.setAllowInclude(arg.allowInclude);
|
||||
command.setAddOrders(arg.addOrders);
|
||||
command.setAddResources(arg.addResources);
|
||||
command.setUpdateOrders(arg.updateOrders);
|
||||
|
@ -72,6 +92,6 @@ public class XmlImportModelService extends AbstractService<XmlImportModelArgumen
|
|||
logger.info(MessageFormat.format("Loaded {0} Orders", statistics.nrOfOrders)); //$NON-NLS-1$
|
||||
logger.info(MessageFormat.format("Loaded {0} Resources", statistics.nrOfResources)); //$NON-NLS-1$
|
||||
|
||||
return ServiceResult.success();
|
||||
return new XmlImportModelResult(statistics);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ public class ServiceExecutionStatus {
|
|||
this.result = svcResult;
|
||||
}
|
||||
|
||||
@XmlAttribute(name = "resultMessage")
|
||||
public String getResultMessage() {
|
||||
@XmlAttribute(name = "msg")
|
||||
public String getMsg() {
|
||||
if (this.result == null)
|
||||
return StringHelper.DASH;
|
||||
if (this.result.getMessage() == null)
|
||||
|
@ -49,8 +49,8 @@ public class ServiceExecutionStatus {
|
|||
return this.result.getMessage();
|
||||
}
|
||||
|
||||
@XmlAttribute(name = "resultState")
|
||||
public String getResultState() {
|
||||
@XmlAttribute(name = "state")
|
||||
public String getState() {
|
||||
if (this.result == null)
|
||||
return StringHelper.DASH;
|
||||
return this.result.getState().name();
|
||||
|
|
Loading…
Reference in New Issue