From 36eb8b86e25326c818c307baf2789c5aada1cc23 Mon Sep 17 00:00:00 2001 From: Phillipus Date: Sun, 29 Dec 2024 16:29:15 +0000 Subject: [PATCH] [Templates] Refactor templates and template manifest handling - De-duplicate lots of code and refactor - Create the template manifest in one place in AbstractTemplate - AbstractTemplate#save() just copies and updates the zip, it doesn't regenerate the thumbnail images --- .../templates/model/CanvasModelTemplate.java | 9 +- .../model/CanvasTemplateManager.java | 67 +----- .../wizard/SaveCanvasAsTemplateWizard.java | 38 +-- .../dialog/TemplateManagerDialog.java | 119 ++++------ .../impl/model/ArchimateModelTemplate.java | 9 +- .../impl/model/ArchimateTemplateManager.java | 68 +----- .../templates/impl/model/Messages.java | 1 - .../templates/impl/model/messages.properties | 3 +- .../SaveArchimateModelAsTemplateWizard.java | 36 +-- .../templates/model/AbstractTemplate.java | 223 +++++++++--------- .../templates/model/ITemplate.java | 17 +- .../templates/model/Messages.java | 4 + .../templates/model/TemplateManager.java | 50 ++-- .../templates/model/messages.properties | 2 + .../NewModelFromTemplateWizardPage.java | 39 ++- 15 files changed, 259 insertions(+), 426 deletions(-) diff --git a/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasModelTemplate.java b/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasModelTemplate.java index 9ed5a60a6..5ba19dd9c 100644 --- a/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasModelTemplate.java +++ b/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasModelTemplate.java @@ -5,6 +5,9 @@ */ package com.archimatetool.canvas.templates.model; +import java.io.File; +import java.io.IOException; + import org.eclipse.swt.graphics.Image; import com.archimatetool.canvas.ICanvasImages; @@ -24,10 +27,10 @@ public class CanvasModelTemplate extends AbstractTemplate { public CanvasModelTemplate() { } - public CanvasModelTemplate(String id) { - super(id); + public CanvasModelTemplate(File file) throws IOException { + super(file); } - + @Override public String getType() { return XML_CANVAS_TEMPLATE_ATTRIBUTE_TYPE_MODEL; diff --git a/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasTemplateManager.java b/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasTemplateManager.java index 413699805..d9694a477 100644 --- a/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasTemplateManager.java +++ b/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/model/CanvasTemplateManager.java @@ -7,22 +7,15 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; import org.eclipse.swt.graphics.Image; -import org.jdom2.Attribute; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; import com.archimatetool.canvas.CanvasEditorPlugin; import com.archimatetool.canvas.ICanvasImages; import com.archimatetool.editor.ArchiPlugin; -import com.archimatetool.editor.utils.ZipUtils; -import com.archimatetool.jdom.JDOMUtils; +import com.archimatetool.editor.Logger; import com.archimatetool.templates.model.ITemplate; import com.archimatetool.templates.model.ITemplateGroup; -import com.archimatetool.templates.model.ITemplateXMLTags; import com.archimatetool.templates.model.TemplateGroup; import com.archimatetool.templates.model.TemplateManager; @@ -37,8 +30,7 @@ public class CanvasTemplateManager extends TemplateManager { public static final String CANVAS_TEMPLATE_FILE_EXTENSION = ".archicanvas"; //$NON-NLS-1$ - private File fUserTemplatesFile = new File(ArchiPlugin.INSTANCE.getWorkspaceFolder(), "canvasses.xml"); //$NON-NLS-1$ - + @Override protected ITemplateGroup loadInbuiltTemplates() { ITemplateGroup group = new TemplateGroup(Messages.CanvasTemplateManager_0); @@ -46,9 +38,12 @@ protected ITemplateGroup loadInbuiltTemplates() { if(folder.exists()) { for(File file : folder.listFiles()) { if(file.getName().toLowerCase().endsWith(CANVAS_TEMPLATE_FILE_EXTENSION)) { - ITemplate template = new CanvasModelTemplate(); - template.setFile(file); - group.addTemplate(template); + try { + group.addTemplate(createTemplate(file)); + } + catch(IOException ex) { + Logger.logError("Error loading template", ex); //$NON-NLS-1$ + } } } } @@ -57,7 +52,7 @@ protected ITemplateGroup loadInbuiltTemplates() { @Override public File getUserTemplatesManifestFile() { - return fUserTemplatesFile; + return new File(ArchiPlugin.INSTANCE.getWorkspaceFolder(), "canvasses.xml"); //$NON-NLS-1$ } @Override @@ -67,53 +62,11 @@ public String getTemplateFileExtension() { @Override public ITemplate createTemplate(File file) throws IOException { - if(isValidTemplateFile(file)) { - return new CanvasModelTemplate(null); - } - else { - throw new IOException("Wrong template format."); //$NON-NLS-1$ - } + return new CanvasModelTemplate(file); } - @Override - protected ITemplate createTemplate(String type) { - if(CanvasModelTemplate.XML_CANVAS_TEMPLATE_ATTRIBUTE_TYPE_MODEL.equals(type)) { - return new CanvasModelTemplate(); - } - return null; - } - @Override public Image getMainImage() { return ICanvasImages.ImageFactory.getImage(ICanvasImages.ICON_CANVAS_MODEL); } - - @Override - protected boolean isValidTemplateFile(File file) throws IOException { - if(file == null || !file.exists()) { - return false; - } - - // Ensure the template is of the right kind - String xmlString = ZipUtils.extractZipEntry(file, ZIP_ENTRY_MANIFEST, Charset.forName("UTF-8")); //$NON-NLS-1$ - if(xmlString == null) { - return false; - } - - // If the attribute "type" exists then return true if its value is "canvas". - // If the attribute doesn't exist it was from an older version (before 2.1) - try { - Document doc = JDOMUtils.readXMLString(xmlString); - Element root = doc.getRootElement(); - Attribute attType = root.getAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TYPE); - if(attType != null) { - return CanvasModelTemplate.XML_CANVAS_TEMPLATE_ATTRIBUTE_TYPE_MODEL.equals(attType.getValue()); - } - } - catch(JDOMException ex) { - return false; - } - - return true; - } } diff --git a/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/wizard/SaveCanvasAsTemplateWizard.java b/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/wizard/SaveCanvasAsTemplateWizard.java index a6f3372a6..06a5cf2eb 100644 --- a/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/wizard/SaveCanvasAsTemplateWizard.java +++ b/com.archimatetool.canvas/src/com/archimatetool/canvas/templates/wizard/SaveCanvasAsTemplateWizard.java @@ -24,8 +24,6 @@ import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -import org.jdom2.Document; -import org.jdom2.Element; import com.archimatetool.canvas.model.ICanvasModel; import com.archimatetool.canvas.templates.model.CanvasModelTemplate; @@ -33,15 +31,14 @@ import com.archimatetool.editor.diagram.commands.DiagramCommandFactory; import com.archimatetool.editor.model.IArchiveManager; import com.archimatetool.editor.utils.ZipUtils; -import com.archimatetool.jdom.JDOMUtils; import com.archimatetool.model.IArchimateFactory; import com.archimatetool.model.IArchimateModel; import com.archimatetool.model.IDiagramModelReference; import com.archimatetool.model.IFolder; import com.archimatetool.model.ModelVersion; import com.archimatetool.model.util.UUIDFactory; +import com.archimatetool.templates.model.ITemplate; import com.archimatetool.templates.model.ITemplateGroup; -import com.archimatetool.templates.model.ITemplateXMLTags; import com.archimatetool.templates.model.TemplateManager; import com.archimatetool.templates.wizard.TemplateUtils; @@ -181,35 +178,16 @@ private void createZipFile(File zipFile) throws IOException { } private String createManifest() throws IOException { - Document doc = new Document(); - Element root = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_MANIFEST); - doc.setRootElement(root); + // Create a new template and create the manifest from that + ITemplate template = new CanvasModelTemplate(); - // Type - root.setAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TYPE, CanvasModelTemplate.XML_CANVAS_TEMPLATE_ATTRIBUTE_TYPE_MODEL); - - // Timestamp - root.setAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TIMESTAMP, Long.toString(System.currentTimeMillis())); - - // Name - Element elementName = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_NAME); - elementName.setText(fTemplateName); - root.addContent(elementName); - - // Description - Element elementDescription = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_DESCRIPTION); - elementDescription.setText(fTemplateDescription); - root.addContent(elementDescription); - - // Thumbnail + template.setName(fTemplateName); + template.setDescription(fTemplateDescription); if(fIncludeThumbnail) { - String keyThumb = TemplateManager.ZIP_ENTRY_THUMBNAILS + "1.png"; //$NON-NLS-1$ - Element elementKeyThumb = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_KEY_THUMBNAIL); - elementKeyThumb.setText(keyThumb); - root.addContent(elementKeyThumb); + template.setKeyThumbnailPath(TemplateManager.ZIP_ENTRY_THUMBNAILS + "1.png"); //$NON-NLS-1$ } - - return JDOMUtils.write2XMLString(doc); + + return template.createManifest(); } private File saveModelToTempFile() throws IOException { diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/dialog/TemplateManagerDialog.java b/com.archimatetool.templates/src/com/archimatetool/templates/dialog/TemplateManagerDialog.java index 132769552..8e03884dd 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/dialog/TemplateManagerDialog.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/dialog/TemplateManagerDialog.java @@ -7,15 +7,14 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; @@ -23,8 +22,6 @@ import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; @@ -78,7 +75,7 @@ public class TemplateManagerDialog extends ExtendedTitleAreaDialog { protected ITemplate fSelectedTemplate; protected ITemplateGroup fSelectedTemplateGroup; - protected List fModifiedTemplates = new ArrayList(); + protected Set fModifiedTemplates = new HashSet<>(); protected TemplateManager fTemplateManager; @@ -138,7 +135,7 @@ protected Control createDialogArea(Composite parent) { fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { - Object o = ((IStructuredSelection)event.getSelection()).getFirstElement(); + Object o = event.getStructuredSelection().getFirstElement(); fSelectedControl = fTableViewer; updateControls(o); } @@ -161,7 +158,7 @@ public void selectionChanged(SelectionChangedEvent event) { fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { - Object o = ((IStructuredSelection)event.getSelection()).getFirstElement(); + Object o = event.getStructuredSelection().getFirstElement(); fSelectedControl = fTreeViewer; updateControls(o); } @@ -226,28 +223,23 @@ public void widgetSelected(SelectionEvent e) { fNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); fNameTextField.setEnabled(false); - fNameTextField.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - String text = fNameTextField.getText(); - if(fIsSettingFields || !StringUtils.isSet(text)) { - return; - } - - // Edit Template name - if(fSelectedTemplate != null) { - fSelectedTemplate.setName(text); - if(!fModifiedTemplates.contains(fSelectedTemplate)) { - fModifiedTemplates.add(fSelectedTemplate); - } - fTableViewer.refresh(); - fTreeViewer.refresh(); - } - // Edit Group name - else if(fSelectedTemplateGroup != null) { - fSelectedTemplateGroup.setName(text); - fTreeViewer.refresh(); - } + fNameTextField.addModifyListener(e -> { + String text = fNameTextField.getText(); + if(fIsSettingFields || !StringUtils.isSet(text)) { + return; + } + + // Edit Template name + if(fSelectedTemplate != null) { + fSelectedTemplate.setName(text); + fModifiedTemplates.add(fSelectedTemplate); + fTableViewer.refresh(); + fTreeViewer.refresh(); + } + // Edit Group name + else if(fSelectedTemplateGroup != null) { + fSelectedTemplateGroup.setName(text); + fTreeViewer.refresh(); } }); @@ -260,19 +252,14 @@ else if(fSelectedTemplateGroup != null) { gd = new GridData(GridData.FILL_BOTH); gd.heightHint = 100; fDescriptionTextField.setLayoutData(gd); - fDescriptionTextField.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - String text = fDescriptionTextField.getText(); - if(fIsSettingFields || !StringUtils.isSet(text)) { - return; - } - if(fSelectedTemplate != null) { - fSelectedTemplate.setDescription(fDescriptionTextField.getText()); - if(!fModifiedTemplates.contains(fSelectedTemplate)) { - fModifiedTemplates.add(fSelectedTemplate); - } - } + fDescriptionTextField.addModifyListener(e -> { + String text = fDescriptionTextField.getText(); + if(fIsSettingFields || !StringUtils.isSet(text)) { + return; + } + if(fSelectedTemplate != null) { + fSelectedTemplate.setDescription(fDescriptionTextField.getText()); + fModifiedTemplates.add(fSelectedTemplate); } }); @@ -339,18 +326,13 @@ protected void openTemplate() { return; } - BusyIndicator.showWhile(null, new Runnable() { - @Override - public void run() { - try { - ITemplate template = fTemplateManager.createTemplate(file); - template.setFile(file); - fTemplateManager.addUserTemplate(template); - fTableViewer.refresh(); - } - catch(IOException ex) { - MessageDialog.openError(getShell(), Messages.TemplateManagerDialog_18, ex.getMessage()); - } + BusyIndicator.showWhile(null, () -> { + try { + fTemplateManager.addUserTemplate(fTemplateManager.createTemplate(file)); + fTableViewer.refresh(); + } + catch(IOException ex) { + MessageDialog.openError(getShell(), Messages.TemplateManagerDialog_18, ex.getMessage()); } }); } @@ -398,11 +380,11 @@ boolean hasGroup(String name) { protected void deleteSelectedObjects() { // Table if(fSelectedControl == fTableViewer) { - for(Object o : ((IStructuredSelection)fTableViewer.getSelection()).toArray()) { - if(o instanceof ITemplate) { - fTemplateManager.getUserTemplates().remove(o); + for(Object o : fTableViewer.getStructuredSelection().toArray()) { + if(o instanceof ITemplate template) { + fTemplateManager.getUserTemplates().remove(template); for(ITemplateGroup group : fTemplateManager.getUserTemplateGroups()) { - group.removeTemplate((ITemplate)o); + group.removeTemplate(template); } } } @@ -413,15 +395,14 @@ protected void deleteSelectedObjects() { else if(fSelectedControl == fTreeViewer) { // Do it this way because we can't get template parents for(TreeItem item : fTreeViewer.getTree().getSelection()) { - if(item.getData() instanceof ITemplate) { - ITemplate template = (ITemplate)item.getData(); + if(item.getData() instanceof ITemplate template) { TreeItem parent = item.getParentItem(); - if(parent.getData() instanceof ITemplateGroup) { - ((ITemplateGroup)parent.getData()).removeTemplate(template); + if(parent.getData() instanceof ITemplateGroup group) { + group.removeTemplate(template); } } - else if(item.getData() instanceof ITemplateGroup) { - fTemplateManager.getUserTemplateGroups().remove(item.getData()); + else if(item.getData() instanceof ITemplateGroup group) { + fTemplateManager.getUserTemplateGroups().remove(group); } } fTreeViewer.refresh(); @@ -447,16 +428,16 @@ protected void updateControls(Object o) { // Buttons fButtonRemove.setEnabled(o instanceof ITemplate || o instanceof ITemplateGroup); - if(o instanceof ITemplate) { - fSelectedTemplate = (ITemplate)o; + if(o instanceof ITemplate template) { + fSelectedTemplate = template; fSelectedTemplateGroup = null; fNameTextField.setText(StringUtils.safeString(fSelectedTemplate.getName())); fDescriptionTextField.setText(StringUtils.safeString(fSelectedTemplate.getDescription())); fFileTextField.setText(StringUtils.safeString(fSelectedTemplate.getFile().getAbsolutePath())); } - else if(o instanceof ITemplateGroup) { + else if(o instanceof ITemplateGroup group) { fSelectedTemplate = null; - fSelectedTemplateGroup = (ITemplateGroup)o; + fSelectedTemplateGroup = group; fNameTextField.setText(StringUtils.safeString(fSelectedTemplateGroup.getName())); } diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateModelTemplate.java b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateModelTemplate.java index d07a00799..e9577862c 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateModelTemplate.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateModelTemplate.java @@ -5,6 +5,9 @@ */ package com.archimatetool.templates.impl.model; +import java.io.File; +import java.io.IOException; + import org.eclipse.swt.graphics.Image; import com.archimatetool.editor.ui.IArchiImages; @@ -24,10 +27,10 @@ public class ArchimateModelTemplate extends AbstractTemplate { public ArchimateModelTemplate() { } - public ArchimateModelTemplate(String id) { - super(id); + public ArchimateModelTemplate(File file) throws IOException { + super(file); } - + @Override public Image getImage() { return IArchiImages.ImageFactory.getImage(IArchiImages.ICON_MODELS); diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateTemplateManager.java b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateTemplateManager.java index 4d391f550..88904d0b0 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateTemplateManager.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/ArchimateTemplateManager.java @@ -7,22 +7,15 @@ import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; import org.eclipse.swt.graphics.Image; -import org.jdom2.Attribute; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; import com.archimatetool.editor.ArchiPlugin; +import com.archimatetool.editor.Logger; import com.archimatetool.editor.ui.IArchiImages; -import com.archimatetool.editor.utils.ZipUtils; -import com.archimatetool.jdom.JDOMUtils; import com.archimatetool.templates.ArchiTemplatesPlugin; import com.archimatetool.templates.model.ITemplate; import com.archimatetool.templates.model.ITemplateGroup; -import com.archimatetool.templates.model.ITemplateXMLTags; import com.archimatetool.templates.model.TemplateGroup; import com.archimatetool.templates.model.TemplateManager; @@ -38,21 +31,22 @@ public class ArchimateTemplateManager extends TemplateManager { public static final String ARCHIMATE_TEMPLATE_FILE_EXTENSION = ".architemplate"; //$NON-NLS-1$ - private File fUserTemplatesFile = new File(ArchiPlugin.INSTANCE.getWorkspaceFolder(), "templates.xml"); //$NON-NLS-1$ - public ArchimateTemplateManager() { } @Override protected ITemplateGroup loadInbuiltTemplates() { - ITemplateGroup group = new TemplateGroup(Messages.ArchimateTemplateManager_2); + ITemplateGroup group = new TemplateGroup(Messages.ArchimateTemplateManager_0); File folder = ArchiTemplatesPlugin.INSTANCE.getTemplatesFolder(); if(folder.exists()) { for(File file : folder.listFiles()) { if(file.getName().toLowerCase().endsWith(ARCHIMATE_TEMPLATE_FILE_EXTENSION)) { - ITemplate template = new ArchimateModelTemplate(); - template.setFile(file); - group.addTemplate(template); + try { + group.addTemplate(createTemplate(file)); + } + catch(IOException ex) { + Logger.logError("Error loading template", ex); //$NON-NLS-1$ + } } } } @@ -61,7 +55,7 @@ protected ITemplateGroup loadInbuiltTemplates() { @Override public File getUserTemplatesManifestFile() { - return fUserTemplatesFile; + return new File(ArchiPlugin.INSTANCE.getWorkspaceFolder(), "templates.xml"); //$NON-NLS-1$ } @Override @@ -71,53 +65,11 @@ public String getTemplateFileExtension() { @Override public ITemplate createTemplate(File file) throws IOException { - if(isValidTemplateFile(file)) { - return new ArchimateModelTemplate(null); - } - else { - throw new IOException(Messages.ArchimateTemplateManager_0); - } + return new ArchimateModelTemplate(file); } - @Override - protected ITemplate createTemplate(String type) { - if(ArchimateModelTemplate.XML_TEMPLATE_ATTRIBUTE_TYPE_MODEL.equals(type)) { - return new ArchimateModelTemplate(); - } - return null; - } - @Override public Image getMainImage() { return IArchiImages.ImageFactory.getImage(IArchiImages.ICON_MODELS); } - - @Override - protected boolean isValidTemplateFile(File file) throws IOException { - if(file == null || !file.exists()) { - return false; - } - - // Ensure the template is of the right kind - String xmlString = ZipUtils.extractZipEntry(file, ZIP_ENTRY_MANIFEST, Charset.forName("UTF-8")); //$NON-NLS-1$ - if(xmlString == null) { - return false; - } - - // If the attribute "type" exists then return true if its value is "model". - // If the attribute doesn't exist it was from an older version (before 2.1) - try { - Document doc = JDOMUtils.readXMLString(xmlString); - Element root = doc.getRootElement(); - Attribute attType = root.getAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TYPE); - if(attType != null) { - return ArchimateModelTemplate.XML_TEMPLATE_ATTRIBUTE_TYPE_MODEL.equals(attType.getValue()); - } - } - catch(JDOMException ex) { - return false; - } - - return true; - } } diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/Messages.java b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/Messages.java index c10a4e98c..954903277 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/Messages.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/Messages.java @@ -13,7 +13,6 @@ public class Messages extends NLS { public static String ArchimateTemplateManager_0; - public static String ArchimateTemplateManager_2; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/messages.properties b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/messages.properties index 9c7b4882f..3514c8ad0 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/messages.properties +++ b/com.archimatetool.templates/src/com/archimatetool/templates/impl/model/messages.properties @@ -1,2 +1 @@ -ArchimateTemplateManager_0=Wrong template format. -ArchimateTemplateManager_2=Installed Templates +ArchimateTemplateManager_0=Installed Templates diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/impl/wizard/SaveArchimateModelAsTemplateWizard.java b/com.archimatetool.templates/src/com/archimatetool/templates/impl/wizard/SaveArchimateModelAsTemplateWizard.java index 2ae755dc0..7abf01dca 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/impl/wizard/SaveArchimateModelAsTemplateWizard.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/impl/wizard/SaveArchimateModelAsTemplateWizard.java @@ -20,19 +20,15 @@ import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -import org.jdom2.Document; -import org.jdom2.Element; import com.archimatetool.editor.model.IArchiveManager; import com.archimatetool.editor.utils.ZipUtils; -import com.archimatetool.jdom.JDOMUtils; import com.archimatetool.model.IArchimateModel; import com.archimatetool.model.IDiagramModel; import com.archimatetool.templates.impl.model.ArchimateModelTemplate; import com.archimatetool.templates.impl.model.ArchimateTemplateManager; import com.archimatetool.templates.model.ITemplate; import com.archimatetool.templates.model.ITemplateGroup; -import com.archimatetool.templates.model.ITemplateXMLTags; import com.archimatetool.templates.model.TemplateManager; import com.archimatetool.templates.wizard.SaveModelAsTemplateToCollectionWizardPage; import com.archimatetool.templates.wizard.TemplateUtils; @@ -190,34 +186,16 @@ else if(count <= ITemplate.MAX_THUMBNAILS) { //others } private String createManifest() throws IOException { - Document doc = new Document(); - Element root = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_MANIFEST); - doc.setRootElement(root); + // Create a new template and create the manifest from that + ITemplate template = new ArchimateModelTemplate(); - // Type - root.setAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TYPE, ArchimateModelTemplate.XML_TEMPLATE_ATTRIBUTE_TYPE_MODEL); - - // Timestamp - root.setAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TIMESTAMP, Long.toString(System.currentTimeMillis())); - - // Name - Element elementName = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_NAME); - elementName.setText(fTemplateName); - root.addContent(elementName); - - // Description - Element elementDescription = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_DESCRIPTION); - elementDescription.setText(fTemplateDescription); - root.addContent(elementDescription); - - // Key thumbnail + template.setName(fTemplateName); + template.setDescription(fTemplateDescription); if(fIncludeThumbnails) { - Element elementKeyThumb = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_KEY_THUMBNAIL); - elementKeyThumb.setText(TemplateManager.ZIP_ENTRY_THUMBNAILS + "1.png"); //$NON-NLS-1$ - root.addContent(elementKeyThumb); + template.setKeyThumbnailPath(TemplateManager.ZIP_ENTRY_THUMBNAILS + "1.png"); //$NON-NLS-1$ } - - return JDOMUtils.write2XMLString(doc); + + return template.createManifest(); } private File saveModelToTempFile() throws IOException { diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/model/AbstractTemplate.java b/com.archimatetool.templates/src/com/archimatetool/templates/model/AbstractTemplate.java index 8b3355b6e..5f3702754 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/model/AbstractTemplate.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/model/AbstractTemplate.java @@ -11,15 +11,17 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.file.Files; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.zip.ZipOutputStream; -import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.jdom2.Document; import org.jdom2.Element; +import org.jdom2.JDOMException; import com.archimatetool.editor.ui.IArchiImages; import com.archimatetool.editor.utils.FileUtils; @@ -35,39 +37,27 @@ * * @author Phillip Beauvoir */ -@SuppressWarnings("nls") public abstract class AbstractTemplate implements ITemplate, ITemplateXMLTags { private String fID; - private String fName; - private String fDescription; - private File fFile; - - private boolean fManifestLoaded; - + private String fName = ""; //$NON-NLS-1$ + private String fDescription = ""; //$NON-NLS-1$ private String fKeyThumbnailPath; + + private File fFile; private Map fThumbnails = new HashMap<>(); private int fThumbnailCount = -1; public AbstractTemplate() { } - - /** - * @param id If this is null a new id will be generated - */ - public AbstractTemplate(String id) { - if(id == null) { - id = UUID.randomUUID().toString(); - } - fID = id; + + public AbstractTemplate(File file) throws IOException { + setFile(file); } @Override public String getName() { - if(!fManifestLoaded) { - loadManifest(); - } return fName; } @@ -78,9 +68,6 @@ public void setName(String name) { @Override public String getDescription() { - if(!fManifestLoaded) { - loadManifest(); - } return fDescription; } @@ -96,7 +83,7 @@ public int getThumbnailCount() { try { for(String s : ZipUtils.getZipFileEntryNames(fFile)) { - if(s.endsWith(".png")) { + if(s.endsWith(".png")) { //$NON-NLS-1$ fThumbnailCount++; } } @@ -109,17 +96,18 @@ public int getThumbnailCount() { return fThumbnailCount; } + @Override + public void setKeyThumbnailPath(String path) { + fKeyThumbnailPath = path; + } + @Override public Image getKeyThumbnail() { - if(!fManifestLoaded) { - loadManifest(); - } - if(fKeyThumbnailPath != null) { try { - String imageNumber = fKeyThumbnailPath.replaceAll("[^0-9]+", ""); + String imageNumber = fKeyThumbnailPath.replaceAll("[^0-9]+", ""); //$NON-NLS-1$ //$NON-NLS-2$ int index = Integer.parseInt(imageNumber); - return getThumbnail(index - 1); + return getThumbnail(index); } catch(Exception ex) { } @@ -133,7 +121,7 @@ public Image getThumbnail(int index) { Image image = fThumbnails.get(index); if(image == null) { - image = loadImage(getThumbnailEntryName(index)); + image = loadThumbnailImage(getThumbnailEntryName(index)); if(image != null) { fThumbnails.put(index, image); } @@ -148,12 +136,17 @@ public File getFile() { } @Override - public void setFile(File file) { + public void setFile(File file) throws IOException { fFile = file; + loadManifest(file); } @Override public String getID() { + if(fID == null) { + fID = UUID.randomUUID().toString(); + } + return fID; } @@ -168,127 +161,125 @@ public void save() throws IOException { return; } - // Create Manifest as JDOM + // Extract zip contents to temp folder + File tmpFolder = Files.createTempDirectory("architemplate").toFile(); //$NON-NLS-1$ + ZipUtils.unpackZip(fFile, tmpFolder); + + // Save this manifest to the temp folder + JDOMUtils.write2XMLFile(createManifestDocument(), new File(tmpFolder, TemplateManager.ZIP_ENTRY_MANIFEST)); + + // Create a new zip file from the temp folder + try(BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fFile))) { + try(ZipOutputStream zOut = new ZipOutputStream(out)) { + ZipUtils.addFolderToZip(tmpFolder, zOut, null, null); + } + } + + // Clean up + FileUtils.deleteFolder(tmpFolder); + } + + @Override + public String createManifest() throws IOException { + return JDOMUtils.write2XMLString(createManifestDocument()); + } + + private Document createManifestDocument() { Document doc = new Document(); Element root = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_MANIFEST); doc.setRootElement(root); + // Type + root.setAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TYPE, getType()); + + // Timestamp + root.setAttribute(ITemplateXMLTags.XML_TEMPLATE_ATTRIBUTE_TIMESTAMP, Long.toString(System.currentTimeMillis())); + + // Name Element elementName = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_NAME); elementName.setText(getName()); root.addContent(elementName); + // Description Element elementDescription = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_DESCRIPTION); elementDescription.setText(getDescription()); root.addContent(elementDescription); + // Key thumbnail if(fKeyThumbnailPath != null) { Element elementKeyThumb = new Element(ITemplateXMLTags.XML_TEMPLATE_ELEMENT_KEY_THUMBNAIL); elementKeyThumb.setText(fKeyThumbnailPath); root.addContent(elementKeyThumb); } - - // Open a zip stream - File tmpFile = File.createTempFile("architemplate", null); - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tmpFile)); - ZipOutputStream zOut = new ZipOutputStream(out); - - // Add Manifest - String manifest = JDOMUtils.write2XMLString(doc); - ZipUtils.addStringToZip(manifest, TemplateManager.ZIP_ENTRY_MANIFEST, zOut, Charset.forName("UTF-8")); - - // Add Model - // Save to temporary file rather than string because the actual encoding can either be ANSI or UTF-8 depending on content - File modelFile = ZipUtils.extractZipEntry(fFile, TemplateManager.ZIP_ENTRY_MODEL, File.createTempFile("archi", null)); - ZipUtils.addFileToZip(modelFile, TemplateManager.ZIP_ENTRY_MODEL, zOut); - modelFile.delete(); - // Thumbnails - for(int i = 0; i < getThumbnailCount(); i++) { - Image image = getThumbnail(i); - if(image != null) { - ZipUtils.addImageToZip(image, getThumbnailEntryName(i), zOut, SWT.IMAGE_PNG, null); - } + return doc; + } + + private void loadManifest(File file) throws IOException { + if(file == null || !file.exists()) { + throw new IOException(Messages.AbstractTemplate_0); } - zOut.flush(); - zOut.close(); + // Manifest + String manifest = ZipUtils.extractZipEntry(file, TemplateManager.ZIP_ENTRY_MANIFEST, Charset.forName("UTF-8")); //$NON-NLS-1$ + if(manifest == null) { + return; + } - // Delete and copy - fFile.delete(); - FileUtils.copyFile(tmpFile, fFile, false); - tmpFile.delete(); - } - - private void loadManifest() { - // Default first - fManifestLoaded = true; - fName = ""; - fDescription = ""; + Document doc = null; + try { + doc = JDOMUtils.readXMLString(manifest); + } + catch(JDOMException ex) { + throw new IOException(ex); + } - if(fFile != null && fFile.exists()) { - try { - // Manifest - String manifest = ZipUtils.extractZipEntry(fFile, TemplateManager.ZIP_ENTRY_MANIFEST, Charset.forName("UTF-8")); - if(manifest != null) { - Document doc = JDOMUtils.readXMLString(manifest); - Element rootElement = doc.getRootElement(); - - // Name - Element nameElement = rootElement.getChild(XML_TEMPLATE_ELEMENT_NAME); - if(nameElement != null) { - fName = nameElement.getText(); - } - - // Description - Element descriptionElement = rootElement.getChild(XML_TEMPLATE_ELEMENT_DESCRIPTION); - if(nameElement != null) { - fDescription = descriptionElement.getText(); - } - - // Key thumbnail - Element keyThumbnailElement = rootElement.getChild(XML_TEMPLATE_ELEMENT_KEY_THUMBNAIL); - if(keyThumbnailElement != null) { - fKeyThumbnailPath = keyThumbnailElement.getText(); - } - } - } - catch(Exception ex) { - ex.printStackTrace(); - } + Element rootElement = doc.getRootElement(); + + // Check type, if any + // If the attribute doesn't exist it was from an older version (before 2.1) + // Or the manifest was edited in the TemplateManagerDialog and type wasn' saved (before this was fixed) + String attType = rootElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_TYPE); + if(attType != null && !Objects.equals(getType(), attType)) { + throw new IOException(Messages.AbstractTemplate_1); + } + + // Name + Element nameElement = rootElement.getChild(XML_TEMPLATE_ELEMENT_NAME); + if(nameElement != null) { + fName = nameElement.getText(); + } + + // Description + Element descriptionElement = rootElement.getChild(XML_TEMPLATE_ELEMENT_DESCRIPTION); + if(nameElement != null) { + fDescription = descriptionElement.getText(); + } + + // Key thumbnail + Element keyThumbnailElement = rootElement.getChild(XML_TEMPLATE_ELEMENT_KEY_THUMBNAIL); + if(keyThumbnailElement != null) { + fKeyThumbnailPath = keyThumbnailElement.getText(); } } - private Image loadImage(String imgName) { - Image image = null; - + private Image loadThumbnailImage(String imgName) { if(fFile != null && fFile.exists() && imgName != null) { - InputStream stream = null; - try { - stream = ZipUtils.getZipEntryStream(fFile, imgName); + try(InputStream stream = ZipUtils.getZipEntryStream(fFile, imgName)) { if(stream != null) { - image = new Image(null, stream); + return new Image(null, stream); } } catch(IOException ex) { ex.printStackTrace(); } - finally { - try { - if(stream != null) { - stream.close(); - } - } - catch(IOException ex) { - ex.printStackTrace(); - } - } } - return image; + return null; } private String getThumbnailEntryName(int index) { - return TemplateManager.ZIP_ENTRY_THUMBNAILS + (index + 1) + ".png"; + return TemplateManager.ZIP_ENTRY_THUMBNAILS + index + ".png"; //$NON-NLS-1$ } @Override diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/model/ITemplate.java b/com.archimatetool.templates/src/com/archimatetool/templates/model/ITemplate.java index 50f7a2486..74cb8e800 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/model/ITemplate.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/model/ITemplate.java @@ -57,6 +57,13 @@ public interface ITemplate { * @return An image to represent this template */ Image getImage(); + + /** + * Set key thumbnail path + * + * @param path + */ + void setKeyThumbnailPath(String path); /** * @return The Key Thumbnail Image to use @@ -83,7 +90,7 @@ public interface ITemplate { /** * @param file */ - void setFile(File file); + void setFile(File file) throws IOException; /** * @return @@ -91,7 +98,13 @@ public interface ITemplate { String getType(); /** - * Save the template file + * @return the Manifest + * @throws IOException + */ + String createManifest() throws IOException; + + /** + * Re-save this template * @throws IOException */ void save() throws IOException; diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/model/Messages.java b/com.archimatetool.templates/src/com/archimatetool/templates/model/Messages.java index 4049bc94c..7b2d637e6 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/model/Messages.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/model/Messages.java @@ -11,6 +11,10 @@ public class Messages extends NLS { private static final String BUNDLE_NAME = "com.archimatetool.templates.model.messages"; //$NON-NLS-1$ + public static String AbstractTemplate_0; + + public static String AbstractTemplate_1; + public static String TemplateManager_0; static { // initialize resource bundle diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/model/TemplateManager.java b/com.archimatetool.templates/src/com/archimatetool/templates/model/TemplateManager.java index a158eaed8..28fd3f6ab 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/model/TemplateManager.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/model/TemplateManager.java @@ -15,6 +15,7 @@ import org.jdom2.Document; import org.jdom2.Element; +import com.archimatetool.editor.Logger; import com.archimatetool.jdom.JDOMUtils; @@ -62,7 +63,6 @@ public void addTemplateEntry(File templateFile, ITemplateGroup group) throws IOE } ITemplate template = createTemplate(templateFile); - template.setFile(templateFile); addUserTemplate(template); // Add to user group if(group != null) { @@ -152,44 +152,43 @@ protected void loadUserTemplates() { doc = JDOMUtils.readXMLFile(getUserTemplatesManifestFile()); } catch(Exception ex) { - ex.printStackTrace(); + Logger.logError("Error loading templates manifest", ex); //$NON-NLS-1$ return; } - HashMap userTemplateMap = new HashMap(); + HashMap userTemplateMap = new HashMap<>(); Element rootElement = doc.getRootElement(); // Templates - for(Object child : rootElement.getChildren(XML_TEMPLATE_ELEMENT_TEMPLATE)) { - Element templateElement = (Element)child; - String type = templateElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_TYPE); - ITemplate template = createTemplate(type); - if(template != null) { - String id = templateElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_ID); - String path = templateElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_FILE); - if(id != null && path != null) { - File file = new File(path); - if(file.exists()) { + for(Element templateElement : rootElement.getChildren(XML_TEMPLATE_ELEMENT_TEMPLATE)) { + //String type = templateElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_TYPE); + String id = templateElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_ID); + String path = templateElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_FILE); + if(id != null && path != null) { + File file = new File(path); + if(file.exists()) { + try { + ITemplate template = createTemplate(file); template.setID(id); - template.setFile(file); fUserTemplates.add(template); userTemplateMap.put(id, template); } + catch(IOException ex) { + Logger.logError("Error loading template", ex); //$NON-NLS-1$ + } } } } // Groups - for(Object child : rootElement.getChildren(XML_TEMPLATE_ELEMENT_GROUP)) { - Element groupElement = (Element)child; + for(Element groupElement : rootElement.getChildren(XML_TEMPLATE_ELEMENT_GROUP)) { ITemplateGroup templateGroup = new TemplateGroup(); templateGroup.setName(groupElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_NAME)); fUserTemplateGroups.add(templateGroup); // Template refs - for(Object child2 : groupElement.getChildren(XML_TEMPLATE_ELEMENT_TEMPLATE_REF)) { - Element templateRefElement = (Element)child2; + for(Element templateRefElement : groupElement.getChildren(XML_TEMPLATE_ELEMENT_TEMPLATE_REF)) { String ref = templateRefElement.getAttributeValue(XML_TEMPLATE_ATTRIBUTE_REF); if(ref != null) { ITemplate template = userTemplateMap.get(ref); @@ -286,23 +285,8 @@ protected void disposeUserTemplates() { */ public abstract File getUserTemplatesManifestFile(); - /** - * Create a new Template entry of type - * @param type - * @return a new Template entry of type or null - */ - protected abstract ITemplate createTemplate(String type); - /** * @return An image that represents this Template Manager */ public abstract Image getMainImage(); - - /** - * Check for valid template file - * @param file The file to check - * @return true if file is a valid template file - * @throws IOException if an error loading occurs or if it is the wrong format - */ - protected abstract boolean isValidTemplateFile(File file) throws IOException; } diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/model/messages.properties b/com.archimatetool.templates/src/com/archimatetool/templates/model/messages.properties index fc4fa623f..364166ecf 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/model/messages.properties +++ b/com.archimatetool.templates/src/com/archimatetool/templates/model/messages.properties @@ -1 +1,3 @@ +AbstractTemplate_0=File doesn't exist. +AbstractTemplate_1=Wrong template format. TemplateManager_0=All diff --git a/com.archimatetool.templates/src/com/archimatetool/templates/wizard/NewModelFromTemplateWizardPage.java b/com.archimatetool.templates/src/com/archimatetool/templates/wizard/NewModelFromTemplateWizardPage.java index 73221b737..f078eb7b5 100644 --- a/com.archimatetool.templates/src/com/archimatetool/templates/wizard/NewModelFromTemplateWizardPage.java +++ b/com.archimatetool.templates/src/com/archimatetool/templates/wizard/NewModelFromTemplateWizardPage.java @@ -301,20 +301,15 @@ protected void handleOpenAction() { final File file = new File(path); // Create template and Finish - BusyIndicator.showWhile(null, new Runnable() { - @Override - public void run() { - try { - ITemplate template = fTemplateManager.createTemplate(file); - template.setFile(file); - fSelectedTemplate = template; - ((ExtendedWizardDialog)getContainer()).finishPressed(); - } - catch(IOException ex) { - MessageDialog.openError(getShell(), Messages.NewModelFromTemplateWizardPage_5, ex.getMessage()); - selectFirstTableItem(); - getContainer().getShell().setVisible(true); - } + BusyIndicator.showWhile(null, () -> { + try { + fSelectedTemplate = fTemplateManager.createTemplate(file); + ((ExtendedWizardDialog)getContainer()).finishPressed(); + } + catch(IOException ex) { + MessageDialog.openError(getShell(), Messages.NewModelFromTemplateWizardPage_5, ex.getMessage()); + selectFirstTableItem(); + getContainer().getShell().setVisible(true); } }); } @@ -366,7 +361,7 @@ private void selectFirstTableItem() { private void registerMouseMoveHandler() { fGallery.addMouseMoveListener(new MouseMoveListener() { int mouse_movement_factor = 6; - int index = 0; + int index = 1; GalleryItem selectedItem; int last_x; @@ -377,7 +372,7 @@ public void mouseMove(MouseEvent event) { // Not enough thumbnails if(item != null) { ITemplate template = (ITemplate)item.getData(); - if(template.getThumbnailCount() < 2) { + if(template.getThumbnailCount() <= 1) { return; } } @@ -389,7 +384,7 @@ public void mouseMove(MouseEvent event) { } selectedItem = item; - index = 0; + index = 1; last_x = event.x; } @@ -397,15 +392,13 @@ public void mouseMove(MouseEvent event) { ITemplate template = (ITemplate)item.getData(); if(event.x < last_x - mouse_movement_factor) { - index--; - if(index < 0) { - index = template.getThumbnailCount() - 1; + if(--index < 1) { + index = template.getThumbnailCount(); } } else if(event.x > last_x + mouse_movement_factor) { - index++; - if(index == template.getThumbnailCount()) { - index = 0; + if(++index > template.getThumbnailCount()) { + index = 1; } } else {