From 03cdee30129fab022a1c6a4fe6d7d9e9f43fc0e0 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 30 Jan 2014 00:21:34 +0100 Subject: [PATCH] [New] Implemented Export and Import model services and commands --- .../command/XmlExportModelCommand.java | 188 ++++++++++++++++++ .../command/XmlImportModelCommand.java | 134 +++++++++++++ .../service/XmlExportModelArgument.java | 31 +++ .../service/XmlExportModelService.java | 73 +++++++ .../service/XmlImportModelArgument.java | 33 +++ ...ervice.java => XmlImportModelService.java} | 35 ++-- 6 files changed, 476 insertions(+), 18 deletions(-) create mode 100644 src/main/java/li/strolch/command/XmlExportModelCommand.java create mode 100644 src/main/java/li/strolch/command/XmlImportModelCommand.java create mode 100644 src/main/java/li/strolch/service/XmlExportModelArgument.java create mode 100644 src/main/java/li/strolch/service/XmlExportModelService.java create mode 100644 src/main/java/li/strolch/service/XmlImportModelArgument.java rename src/main/java/li/strolch/service/{ImportModelFromXmlService.java => XmlImportModelService.java} (67%) diff --git a/src/main/java/li/strolch/command/XmlExportModelCommand.java b/src/main/java/li/strolch/command/XmlExportModelCommand.java new file mode 100644 index 000000000..447ec93c1 --- /dev/null +++ b/src/main/java/li/strolch/command/XmlExportModelCommand.java @@ -0,0 +1,188 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.command; + +import java.io.File; +import java.io.FileOutputStream; +import java.text.MessageFormat; +import java.util.Date; +import java.util.Set; +import java.util.TreeSet; + +import javanet.staxutils.IndentingXMLStreamWriter; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamWriter; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.agent.api.OrderMap; +import li.strolch.agent.api.ResourceMap; +import li.strolch.exception.StrolchException; +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; +import li.strolch.model.Tags; +import li.strolch.model.xml.OrderToSaxWriterVisitor; +import li.strolch.model.xml.ResourceToSaxWriterVisitor; +import li.strolch.model.xml.XmlModelSaxReader.XmlModelStatistics; +import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.runtime.StrolchConstants; +import li.strolch.service.api.Command; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public class XmlExportModelCommand extends Command { + + // input + private File modelFile; + private boolean doOrders; + private boolean doResources; + private Set orderTypes; + private Set resourceTypes; + + // output + private XmlModelStatistics statistics; + + /** + * @param container + * @param tx + */ + public XmlExportModelCommand(ComponentContainer container, StrolchTransaction tx) { + super(container, tx); + } + + @Override + public void doCommand() { + DBC.PRE.assertNotExists("Model may not already exist!", this.modelFile); + + this.statistics = new XmlModelStatistics(); + this.statistics.startTime = new Date(); + long start = System.nanoTime(); + + try (FileOutputStream out = new FileOutputStream(this.modelFile)) { + + XMLOutputFactory factory = XMLOutputFactory.newInstance(); + XMLStreamWriter writer = factory.createXMLStreamWriter(out, StrolchConstants.DEFAULT_ENCODING); + writer = new IndentingXMLStreamWriter(writer); + + // start document + writer.writeStartDocument(StrolchConstants.DEFAULT_ENCODING, StrolchConstants.DEFAULT_XML_VERSION); + writer.writeStartElement(Tags.STROLCH_MODEL); + + if (doResources) { + ResourceMap resourceMap = tx().getResourceMap(); + Set resourceTypesToExport = resourceMap.getTypes(tx()); + if (!this.resourceTypes.isEmpty()) + resourceTypesToExport.retainAll(resourceTypes); + + resourceTypesToExport = new TreeSet<>(resourceTypesToExport); + ResourceVisitor visitor = new ResourceToSaxWriterVisitor(writer); + for (String type : resourceTypesToExport) { + Set keysByType = new TreeSet<>(resourceMap.getKeysBy(tx(), type)); + for (String id : keysByType) { + Resource resource = resourceMap.getBy(tx(), type, id); + visitor.visit(resource); + statistics.nrOfResources++; + } + } + } + + if (doOrders) { + OrderMap orderMap = tx().getOrderMap(); + Set orderTypesToExport = orderMap.getTypes(tx()); + if (!this.orderTypes.isEmpty()) + orderTypesToExport.retainAll(orderTypes); + + orderTypesToExport = new TreeSet<>(orderTypesToExport); + OrderVisitor visitor = new OrderToSaxWriterVisitor(writer); + for (String type : orderTypesToExport) { + Set keysByType = new TreeSet<>(orderMap.getKeysBy(tx(), type)); + for (String id : keysByType) { + Order order = orderMap.getBy(tx(), type, id); + visitor.visit(order); + statistics.nrOfOrders++; + } + } + } + + // and now end + writer.writeEndElement(); + writer.writeEndDocument(); + writer.flush(); + + writer.close(); + + this.statistics.durationNanos = System.nanoTime() - start; + + } catch (Exception e) { + if (modelFile.exists()) + modelFile.delete(); + String msg = "Failed to write model to file {0} due to {1}"; + msg = MessageFormat.format(msg, modelFile, e.getMessage()); + throw new StrolchException(msg, e); + } + } + + /** + * @param modelFile + * the modelFile to set + */ + public void setModelFile(File modelFile) { + this.modelFile = modelFile; + } + + /** + * @param doOrders + * the doOrders to set + */ + public void setDoOrders(boolean doOrders) { + this.doOrders = doOrders; + } + + /** + * @param doResources + * the doResources to set + */ + public void setDoResources(boolean doResources) { + this.doResources = doResources; + } + + /** + * @param orderTypes + * the orderTypes to set + */ + public void setOrderTypes(Set orderTypes) { + this.orderTypes = orderTypes; + } + + /** + * @param resourceTypes + * the resourceTypes to set + */ + public void setResourceTypes(Set resourceTypes) { + this.resourceTypes = resourceTypes; + } + + /** + * @return the statistics + */ + public XmlModelStatistics getStatistics() { + return this.statistics; + } +} diff --git a/src/main/java/li/strolch/command/XmlImportModelCommand.java b/src/main/java/li/strolch/command/XmlImportModelCommand.java new file mode 100644 index 000000000..a5d00eeae --- /dev/null +++ b/src/main/java/li/strolch/command/XmlImportModelCommand.java @@ -0,0 +1,134 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.command; + +import java.io.File; +import java.util.Set; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.agent.impl.InMemoryElementListener; +import li.strolch.model.xml.XmlModelSaxFileReader; +import li.strolch.model.xml.XmlModelSaxReader.XmlModelStatistics; +import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.service.api.Command; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public class XmlImportModelCommand extends Command { + + // input + private File modelFile; + private boolean addOrders; + private boolean addResources; + private boolean updateOrders; + private boolean updateResources; + private Set orderTypes; + private Set resourceTypes; + + // output + private XmlModelStatistics statistics; + + /** + * @param container + * @param tx + */ + public XmlImportModelCommand(ComponentContainer container, StrolchTransaction tx) { + super(container, tx); + } + + @Override + public void doCommand() { + DBC.PRE.assertExists("Model must exist!", this.modelFile); + + InMemoryElementListener elementListener = new InMemoryElementListener(tx()); + + elementListener.setAddOrders(addOrders); + elementListener.setAddResources(addResources); + elementListener.setUpdateOrders(updateOrders); + elementListener.setUpdateResources(updateResources); + elementListener.setOrderTypes(orderTypes); + elementListener.setResourceTypes(resourceTypes); + + XmlModelSaxFileReader handler = new XmlModelSaxFileReader(elementListener, modelFile); + handler.parseFile(); + + statistics = handler.getStatistics(); + } + + /** + * @param modelFileName + */ + public void setModelFile(File modelFileName) { + this.modelFile = modelFileName; + } + + /** + * @param addOrders + * the addOrders to set + */ + public void setAddOrders(boolean addOrders) { + this.addOrders = addOrders; + } + + /** + * @param addResources + * the addResources to set + */ + public void setAddResources(boolean addResources) { + this.addResources = addResources; + } + + /** + * @param updateOrders + * the updateOrders to set + */ + public void setUpdateOrders(boolean updateOrders) { + this.updateOrders = updateOrders; + } + + /** + * @param updateResources + * the updateResources to set + */ + public void setUpdateResources(boolean updateResources) { + this.updateResources = updateResources; + } + + /** + * @param orderTypes + * the orderTypes to set + */ + public void setOrderTypes(Set orderTypes) { + this.orderTypes = orderTypes; + } + + /** + * @param resourceTypes + * the resourceTypes to set + */ + public void setResourceTypes(Set resourceTypes) { + this.resourceTypes = resourceTypes; + } + + /** + * @return the statistics + */ + public XmlModelStatistics getStatistics() { + return this.statistics; + } +} diff --git a/src/main/java/li/strolch/service/XmlExportModelArgument.java b/src/main/java/li/strolch/service/XmlExportModelArgument.java new file mode 100644 index 000000000..6993d79b3 --- /dev/null +++ b/src/main/java/li/strolch/service/XmlExportModelArgument.java @@ -0,0 +1,31 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.service; + +import java.util.HashSet; +import java.util.Set; + +import li.strolch.service.api.ServiceArgument; + +public class XmlExportModelArgument extends ServiceArgument { + private static final long serialVersionUID = 1L; + + public String modelFileName; + public boolean doOrders = true; + public boolean doResources = true; + public Set orderTypes = new HashSet<>(); + public Set resourceTypes = new HashSet<>(); +} \ No newline at end of file diff --git a/src/main/java/li/strolch/service/XmlExportModelService.java b/src/main/java/li/strolch/service/XmlExportModelService.java new file mode 100644 index 000000000..8716ee4cb --- /dev/null +++ b/src/main/java/li/strolch/service/XmlExportModelService.java @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.service; + +import java.io.File; +import java.text.MessageFormat; + +import li.strolch.command.XmlExportModelCommand; +import li.strolch.exception.StrolchException; +import li.strolch.model.xml.XmlModelSaxReader.XmlModelStatistics; +import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.service.api.AbstractService; +import li.strolch.service.api.ServiceResult; +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public class XmlExportModelService extends AbstractService { + + private static final long serialVersionUID = 1L; + + @Override + protected ServiceResult getResultInstance() { + return new ServiceResult(); + } + + @Override + protected ServiceResult internalDoService(XmlExportModelArgument arg) { + + File dataPath = getRuntimeConfiguration().getDataPath(); + File modelFile = new File(dataPath, arg.modelFileName); + if (modelFile.exists()) { + String msg = "Model File already exists with name {0} in data path {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, arg.modelFileName, dataPath); + throw new StrolchException(msg); + } + + XmlModelStatistics statistics; + try (StrolchTransaction tx = openTx(arg.realm)) { + + XmlExportModelCommand command = new XmlExportModelCommand(getContainer(), tx); + command.setModelFile(modelFile); + command.setDoOrders(arg.doOrders); + command.setDoResources(arg.doResources); + command.setOrderTypes(arg.orderTypes); + command.setResourceTypes(arg.resourceTypes); + command.doCommand(); + statistics = command.getStatistics(); + } + + String durationS = StringHelper.formatNanoDuration(statistics.durationNanos); + logger.info(MessageFormat + .format("Writing XML Model file {0} for realm {1} took {2} at path: {3}", modelFile.getName(), arg.realm, durationS, modelFile.getAbsolutePath())); //$NON-NLS-1$ + logger.info(MessageFormat.format("Wrote {0} Orders", statistics.nrOfOrders)); //$NON-NLS-1$ + logger.info(MessageFormat.format("Wrote {0} Resources", statistics.nrOfResources)); //$NON-NLS-1$ + + return ServiceResult.success(); + } +} diff --git a/src/main/java/li/strolch/service/XmlImportModelArgument.java b/src/main/java/li/strolch/service/XmlImportModelArgument.java new file mode 100644 index 000000000..853165c32 --- /dev/null +++ b/src/main/java/li/strolch/service/XmlImportModelArgument.java @@ -0,0 +1,33 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.service; + +import java.util.HashSet; +import java.util.Set; + +import li.strolch.service.api.ServiceArgument; + +public class XmlImportModelArgument extends ServiceArgument { + private static final long serialVersionUID = 1L; + + public String modelFileName; + 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<>(); +} \ No newline at end of file diff --git a/src/main/java/li/strolch/service/ImportModelFromXmlService.java b/src/main/java/li/strolch/service/XmlImportModelService.java similarity index 67% rename from src/main/java/li/strolch/service/ImportModelFromXmlService.java rename to src/main/java/li/strolch/service/XmlImportModelService.java index e4a7dfd35..50dfe92cd 100644 --- a/src/main/java/li/strolch/service/ImportModelFromXmlService.java +++ b/src/main/java/li/strolch/service/XmlImportModelService.java @@ -18,21 +18,18 @@ package li.strolch.service; import java.io.File; import java.text.MessageFormat; -import li.strolch.agent.impl.InMemoryElementListener; +import li.strolch.command.XmlImportModelCommand; import li.strolch.exception.StrolchException; -import li.strolch.model.xml.XmlModelDefaultHandler.XmlModelStatistics; -import li.strolch.model.xml.XmlModelFileHandler; +import li.strolch.model.xml.XmlModelSaxReader.XmlModelStatistics; import li.strolch.persistence.api.StrolchTransaction; import li.strolch.service.api.AbstractService; -import li.strolch.service.api.ServiceArgument; import li.strolch.service.api.ServiceResult; import ch.eitchnet.utils.helper.StringHelper; /** * @author Robert von Burg */ -public class ImportModelFromXmlService extends - AbstractService { +public class XmlImportModelService extends AbstractService { private static final long serialVersionUID = 1L; @@ -42,22 +39,29 @@ public class ImportModelFromXmlService extends } @Override - protected ServiceResult internalDoService(ImportModelFromXmlArg arg) { + protected ServiceResult internalDoService(XmlImportModelArgument arg) { File dataPath = getRuntimeConfiguration().getDataPath(); - File modelFile = new File(dataPath, arg.fileName); + 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.fileName, dataPath); + msg = MessageFormat.format(msg, arg.modelFileName, dataPath); throw new StrolchException(msg); } XmlModelStatistics statistics; try (StrolchTransaction tx = openTx(arg.realm)) { - InMemoryElementListener elementListener = new InMemoryElementListener(tx); - XmlModelFileHandler handler = new XmlModelFileHandler(elementListener, modelFile); - handler.parseFile(); - statistics = handler.getStatistics(); + + XmlImportModelCommand command = new XmlImportModelCommand(getContainer(), tx); + command.setModelFile(modelFile); + command.setAddOrders(arg.addOrders); + command.setAddResources(arg.addResources); + command.setUpdateOrders(arg.updateOrders); + command.setUpdateResources(arg.updateResources); + command.setOrderTypes(arg.orderTypes); + command.setResourceTypes(arg.resourceTypes); + command.doCommand(); + statistics = command.getStatistics(); } String durationS = StringHelper.formatNanoDuration(statistics.durationNanos); @@ -68,9 +72,4 @@ public class ImportModelFromXmlService extends return ServiceResult.success(); } - - public static class ImportModelFromXmlArg extends ServiceArgument { - private static final long serialVersionUID = 1L; - public String fileName; - } }