From a832b2dc3e4cba2cdcc5c01656ac3844cfb233b3 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 28 Feb 2015 20:41:52 +0100 Subject: [PATCH] [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 --- .../li/strolch/agent/impl/TransientRealm.java | 2 +- .../li/strolch/model/ModelStatistics.java | 23 ++++++++++ .../model/xml/XmlModelSaxFileReader.java | 22 ++++++---- .../model/XmlModelDefaultHandlerTest.java | 2 +- .../postgresql/PostgreSqlInitializer.java | 2 +- .../command/XmlImportModelCommand.java | 10 ++++- .../service/XmlExportModelArgument.java | 2 +- .../service/XmlImportModelArgument.java | 43 ++++++++++++++++++ .../service/XmlImportModelService.java | 44 ++++++++++++++----- .../executor/ServiceExecutionStatus.java | 8 ++-- 10 files changed, 129 insertions(+), 29 deletions(-) diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransientRealm.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransientRealm.java index 2abbda884..e470c2769 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransientRealm.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransientRealm.java @@ -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(); diff --git a/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java b/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java index 32315e47e..06e939600 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java +++ b/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java @@ -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 + */ +@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; } diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java b/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java index e87059b6f..d805274f8 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java @@ -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 - * */ 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); } } } diff --git a/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java b/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java index 35f299bb9..24c845d66 100644 --- a/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java +++ b/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java @@ -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()); diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlInitializer.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlInitializer.java index 6a562ef22..4d1af9612 100644 --- a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlInitializer.java +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlInitializer.java @@ -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(); diff --git a/li.strolch.service/src/main/java/li/strolch/command/XmlImportModelCommand.java b/li.strolch.service/src/main/java/li/strolch/command/XmlImportModelCommand.java index 802321513..8da39ca3a 100644 --- a/li.strolch.service/src/main/java/li/strolch/command/XmlImportModelCommand.java +++ b/li.strolch.service/src/main/java/li/strolch/command/XmlImportModelCommand.java @@ -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 diff --git a/li.strolch.service/src/main/java/li/strolch/service/XmlExportModelArgument.java b/li.strolch.service/src/main/java/li/strolch/service/XmlExportModelArgument.java index 977f43f61..fc368bd80 100644 --- a/li.strolch.service/src/main/java/li/strolch/service/XmlExportModelArgument.java +++ b/li.strolch.service/src/main/java/li/strolch/service/XmlExportModelArgument.java @@ -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="); diff --git a/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelArgument.java b/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelArgument.java index 853165c32..d1ddff722 100644 --- a/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelArgument.java +++ b/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelArgument.java @@ -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 orderTypes = new HashSet<>(); public Set 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(); + } } \ No newline at end of file diff --git a/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelService.java b/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelService.java index 0686fea96..55e9f9234 100644 --- a/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelService.java +++ b/li.strolch.service/src/main/java/li/strolch/service/XmlImportModelService.java @@ -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 */ -public class XmlImportModelService extends AbstractService { +public class XmlImportModelService extends AbstractService { 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