Added support for component templates

This commit is contained in:
bancika
2012-08-31 11:10:08 +00:00
parent 8c3c6ea56e
commit 8804295df6
7 changed files with 253 additions and 37 deletions
@@ -5,7 +5,6 @@ import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Point; import java.awt.Point;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -15,6 +14,7 @@ import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.appframework.update.VersionNumber; import org.diylc.appframework.update.VersionNumber;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
import org.diylc.core.Project; import org.diylc.core.Project;
import org.diylc.core.Template;
import org.diylc.core.Theme; import org.diylc.core.Theme;
/** /**
@@ -29,7 +29,7 @@ import org.diylc.core.Theme;
* @see IMessageListener * @see IMessageListener
* @see EventType * @see EventType
*/ */
public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor { public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor, ITemplateProcessor {
public static final String ANTI_ALIASING_KEY = "antiAliasing"; public static final String ANTI_ALIASING_KEY = "antiAliasing";
public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender"; public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender";
@@ -241,8 +241,11 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
/** /**
* Sets the new component slot. Specified component type will be used to * Sets the new component slot. Specified component type will be used to
* instantiate new component. * instantiate new component.
*
* @param componentType
* @param template
*/ */
void setNewComponentTypeSlot(ComponentType componentType); void setNewComponentTypeSlot(ComponentType componentType, Template template);
/** /**
* Changes default size notation, true for metric, false for imperial. * Changes default size notation, true for metric, false for imperial.
@@ -0,0 +1,22 @@
package org.diylc.common;
import java.util.List;
import org.diylc.core.Template;
public interface ITemplateProcessor {
public static final String TEMPLATES_KEY = "templates";
void saveSelectedComponentAsTemplate(String templateName);
List<Template> getTemplatesFor(String categoryName, String componentTypeName);
void deleteTemplate(String categoryName, String componentTypeName, String templateName);
public class TemplateAlreadyExistsException extends Exception {
private static final long serialVersionUID = 1L;
}
}
@@ -0,0 +1,62 @@
package org.diylc.core;
import java.util.Map;
public class Template {
private String name;
private Map<String, Object> values;
public Template(String name, Map<String, Object> values) {
super();
this.name = name;
this.values = values;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Object> getValues() {
return values;
}
public void setValues(Map<String, Object> values) {
this.values = values;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((values == null) ? 0 : values.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Template other = (Template) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (values == null) {
if (other.values != null)
return false;
} else if (!values.equals(other.values))
return false;
return true;
}
}
@@ -4,7 +4,9 @@ import java.awt.Point;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.appframework.miscutils.ConfigurationManager;
@@ -14,6 +16,7 @@ import org.diylc.common.Orientation;
import org.diylc.common.PropertyWrapper; import org.diylc.common.PropertyWrapper;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
import org.diylc.core.Project; import org.diylc.core.Project;
import org.diylc.core.Template;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
/** /**
@@ -29,6 +32,7 @@ public class InstantiationManager {
public static int MAX_RECENT_COMPONENTS = 16; public static int MAX_RECENT_COMPONENTS = 16;
private ComponentType componentTypeSlot; private ComponentType componentTypeSlot;
private Template template;
private IDIYComponent<?> componentSlot; private IDIYComponent<?> componentSlot;
private Point firstControlPoint; private Point firstControlPoint;
private Point potentialControlPoint; private Point potentialControlPoint;
@@ -40,6 +44,10 @@ public class InstantiationManager {
return componentTypeSlot; return componentTypeSlot;
} }
public Template getTemplate() {
return template;
}
public IDIYComponent<?> getComponentSlot() { public IDIYComponent<?> getComponentSlot() {
return componentSlot; return componentSlot;
} }
@@ -53,8 +61,9 @@ public class InstantiationManager {
} }
public void setComponentTypeSlot(ComponentType componentTypeSlot, public void setComponentTypeSlot(ComponentType componentTypeSlot,
Project currentProject) throws Exception { Template template, Project currentProject) throws Exception {
this.componentTypeSlot = componentTypeSlot; this.componentTypeSlot = componentTypeSlot;
this.template = template;
if (componentTypeSlot == null) { if (componentTypeSlot == null) {
this.componentSlot = null; this.componentSlot = null;
} else { } else {
@@ -64,7 +73,7 @@ public class InstantiationManager {
break; break;
case SINGLE_CLICK: case SINGLE_CLICK:
this.componentSlot = instantiateComponent(componentTypeSlot, this.componentSlot = instantiateComponent(componentTypeSlot,
new Point(0, 0), currentProject); template, new Point(0, 0), currentProject);
break; break;
} }
} }
@@ -75,7 +84,7 @@ public class InstantiationManager {
public void instatiatePointByPoint(Point scaledPoint, Project currentProject) public void instatiatePointByPoint(Point scaledPoint, Project currentProject)
throws Exception { throws Exception {
firstControlPoint = scaledPoint; firstControlPoint = scaledPoint;
componentSlot = instantiateComponent(componentTypeSlot, componentSlot = instantiateComponent(componentTypeSlot, template,
firstControlPoint, currentProject); firstControlPoint, currentProject);
// Set the other control point to the same location, we'll // Set the other control point to the same location, we'll
@@ -130,7 +139,8 @@ public class InstantiationManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public IDIYComponent<?> instantiateComponent(ComponentType componentType, public IDIYComponent<?> instantiateComponent(ComponentType componentType,
Point point, Project currentProject) throws Exception { Template template, Point point, Project currentProject)
throws Exception {
LOG.info("Instatiating component of type: " LOG.info("Instatiating component of type: "
+ componentType.getInstanceClass().getName()); + componentType.getInstanceClass().getName());
@@ -150,7 +160,7 @@ public class InstantiationManager {
} }
} }
fillWithDefaultProperties(component); fillWithDefaultProperties(component, template);
// Write to recent components // Write to recent components
List<String> recentComponentTypes = (List<String>) ConfigurationManager List<String> recentComponentTypes = (List<String>) ConfigurationManager
@@ -201,20 +211,23 @@ public class InstantiationManager {
* objects. * objects.
* *
* @param object * @param object
* @param template
* @throws IllegalArgumentException * @throws IllegalArgumentException
* @throws IllegalAccessException * @throws IllegalAccessException
* @throws InvocationTargetException * @throws InvocationTargetException
* @throws NoSuchMethodException * @throws NoSuchMethodException
* @throws SecurityException * @throws SecurityException
*/ */
public void fillWithDefaultProperties(Object object) public void fillWithDefaultProperties(Object object, Template template)
throws IllegalArgumentException, IllegalAccessException, throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException { InvocationTargetException, SecurityException, NoSuchMethodException {
// Extract properties. // Extract properties.
List<PropertyWrapper> properties = ComponentProcessor.getInstance() List<PropertyWrapper> properties = ComponentProcessor.getInstance()
.extractProperties(object.getClass()); .extractProperties(object.getClass());
Map<String, PropertyWrapper> propertyCache = new HashMap<String, PropertyWrapper>();
// Override with default values if available. // Override with default values if available.
for (PropertyWrapper property : properties) { for (PropertyWrapper property : properties) {
propertyCache.put(property.getName(), property);
Object defaultValue = ConfigurationManager.getInstance() Object defaultValue = ConfigurationManager.getInstance()
.readObject( .readObject(
Presenter.DEFAULTS_KEY_PREFIX Presenter.DEFAULTS_KEY_PREFIX
@@ -225,6 +238,18 @@ public class InstantiationManager {
property.writeTo(object); property.writeTo(object);
} }
} }
if (template != null) {
for (Map.Entry<String, Object> pair : template.getValues().entrySet()) {
PropertyWrapper property = propertyCache.get(pair.getKey());
if (property == null) {
LOG.warn("Cannot find property " + pair.getKey());
} else {
LOG.debug("Filling value from template for " + pair.getKey());
property.setValue(pair.getValue());
property.writeTo(object);
}
}
}
} }
public void tryToRotateComponentSlot() { public void tryToRotateComponentSlot() {
@@ -43,6 +43,7 @@ import org.diylc.core.ExpansionMode;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
import org.diylc.core.IView; import org.diylc.core.IView;
import org.diylc.core.Project; import org.diylc.core.Project;
import org.diylc.core.Template;
import org.diylc.core.Theme; import org.diylc.core.Theme;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants; import org.diylc.utils.Constants;
@@ -57,7 +58,7 @@ public class Presenter implements IPlugInPort {
private static final Logger LOG = Logger.getLogger(Presenter.class); private static final Logger LOG = Logger.getLogger(Presenter.class);
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, public static final VersionNumber CURRENT_VERSION = new VersionNumber(3,
14, 0); 15, 0);
public static final String DEFAULTS_KEY_PREFIX = "default."; public static final String DEFAULTS_KEY_PREFIX = "default.";
public static final List<IDIYComponent<?>> EMPTY_SELECTION = Collections public static final List<IDIYComponent<?>> EMPTY_SELECTION = Collections
@@ -203,7 +204,7 @@ public class Presenter implements IPlugInPort {
LOG.info("createNewFile()"); LOG.info("createNewFile()");
try { try {
Project project = new Project(); Project project = new Project();
instantiationManager.fillWithDefaultProperties(project); instantiationManager.fillWithDefaultProperties(project, null);
loadProject(project, true); loadProject(project, true);
projectFileManager.startNewFile(); projectFileManager.startNewFile();
} catch (Exception e) { } catch (Exception e) {
@@ -412,6 +413,7 @@ public class Presenter implements IPlugInPort {
// Keep the reference to component type for later. // Keep the reference to component type for later.
ComponentType componentTypeSlot = instantiationManager ComponentType componentTypeSlot = instantiationManager
.getComponentTypeSlot(); .getComponentTypeSlot();
Template template = instantiationManager.getTemplate();
Project oldProject = currentProject.clone(); Project oldProject = currentProject.clone();
switch (componentTypeSlot.getCreationMethod()) { switch (componentTypeSlot.getCreationMethod()) {
case SINGLE_CLICK: case SINGLE_CLICK:
@@ -445,9 +447,9 @@ public class Presenter implements IPlugInPort {
} }
if (ConfigurationManager.getInstance().readBoolean( if (ConfigurationManager.getInstance().readBoolean(
IPlugInPort.CONTINUOUS_CREATION_KEY, false)) { IPlugInPort.CONTINUOUS_CREATION_KEY, false)) {
setNewComponentTypeSlot(componentTypeSlot); setNewComponentTypeSlot(componentTypeSlot, template);
} else { } else {
setNewComponentTypeSlot(null); setNewComponentTypeSlot(null, null);
} }
break; break;
case POINT_BY_POINT: case POINT_BY_POINT:
@@ -495,9 +497,9 @@ public class Presenter implements IPlugInPort {
} }
if (ConfigurationManager.getInstance().readBoolean( if (ConfigurationManager.getInstance().readBoolean(
IPlugInPort.CONTINUOUS_CREATION_KEY, false)) { IPlugInPort.CONTINUOUS_CREATION_KEY, false)) {
setNewComponentTypeSlot(componentTypeSlot); setNewComponentTypeSlot(componentTypeSlot, template);
} else { } else {
setNewComponentTypeSlot(null); setNewComponentTypeSlot(null, null);
} }
} }
break; break;
@@ -1583,7 +1585,7 @@ public class Presenter implements IPlugInPort {
if (component.isControlPointSticky(i)) { if (component.isControlPointSticky(i)) {
try { try {
IDIYComponent<?> pad = instantiationManager IDIYComponent<?> pad = instantiationManager
.instantiateComponent(padType, component .instantiateComponent(padType, null, component
.getControlPoint(i), currentProject); .getControlPoint(i), currentProject);
pad.setControlPoint(component.getControlPoint(i), 0); pad.setControlPoint(component.getControlPoint(i), 0);
addComponent(pad, padType, false); addComponent(pad, padType, false);
@@ -1688,11 +1690,12 @@ public class Presenter implements IPlugInPort {
} }
@Override @Override
public void setNewComponentTypeSlot(ComponentType componentType) { public void setNewComponentTypeSlot(ComponentType componentType,
Template template) {
LOG.info(String.format("setNewComponentSlot(%s)", LOG.info(String.format("setNewComponentSlot(%s)",
componentType == null ? null : componentType.getName())); componentType == null ? null : componentType.getName()));
try { try {
instantiationManager.setComponentTypeSlot(componentType, instantiationManager.setComponentTypeSlot(componentType, template,
currentProject); currentProject);
if (componentType != null) { if (componentType != null) {
updateSelection(EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
@@ -1714,6 +1717,107 @@ public class Presenter implements IPlugInPort {
} }
} }
@Override
public void saveSelectedComponentAsTemplate(String templateName) {
LOG.info(String.format("saveSelectedComponentAsTemplate(%s)",
templateName));
if (selectedComponents.size() != 1) {
throw new RuntimeException(
"Can only save a single component at a time.");
}
IDIYComponent<?> component = selectedComponents.iterator().next();
ComponentType type = ComponentProcessor.getInstance()
.extractComponentTypeFrom(
(Class<? extends IDIYComponent<?>>) component
.getClass());
Map<String, List<Template>> templateMap = (Map<String, List<Template>>) ConfigurationManager
.getInstance().readObject(TEMPLATES_KEY, null);
if (templateMap == null) {
templateMap = new HashMap<String, List<Template>>();
}
String key = type.getCategory() + "." + type.getName();
List<Template> templates = templateMap.get(key);
if (templates == null) {
templates = new ArrayList<Template>();
templateMap.put(key, templates);
}
List<PropertyWrapper> properties = ComponentProcessor.getInstance()
.extractProperties(component.getClass());
Map<String, Object> values = new HashMap<String, Object>();
for (PropertyWrapper property : properties) {
if (property.getName().equalsIgnoreCase("name")) {
continue;
}
try {
property.readFrom(component);
values.put(property.getName(), property.getValue());
} catch (Exception e) {
}
}
Template template = new Template(templateName, values);
boolean exists = false;
for (Template t : templates) {
if (t.getName().equalsIgnoreCase(templateName)) {
exists = true;
break;
}
}
if (exists) {
int result = view.showConfirmDialog(
"Template with that name already exists. Overwrite?",
"Save as Template", IView.YES_NO_OPTION,
IView.WARNING_MESSAGE);
if (result != IView.YES_OPTION) {
return;
}
// Delete the existing template
Iterator<Template> i = templates.iterator();
while (i.hasNext()) {
Template t = i.next();
if (t.getName().equalsIgnoreCase(templateName)) {
i.remove();
}
}
}
templates.add(template);
ConfigurationManager.getInstance().writeValue(TEMPLATES_KEY,
templateMap);
}
@Override
public List<Template> getTemplatesFor(String categoryName,
String componentTypeName) {
Map<String, List<Template>> templateMap = (Map<String, List<Template>>) ConfigurationManager
.getInstance().readObject(TEMPLATES_KEY, null);
if (templateMap != null) {
return templateMap.get(categoryName + "." + componentTypeName);
}
return null;
}
@Override
public void deleteTemplate(String categoryName, String componentTypeName,
String templateName) {
Map<String, List<Template>> templateMap = (Map<String, List<Template>>) ConfigurationManager
.getInstance().readObject(TEMPLATES_KEY, null);
if (templateMap != null) {
List<Template> templates = templateMap.get(categoryName + "."
+ componentTypeName);
if (templates != null) {
Iterator<Template> i = templates.iterator();
while (i.hasNext()) {
Template t = i.next();
if (t.getName().equalsIgnoreCase(templateName)) {
i.remove();
}
}
}
}
}
private Set<IDIYComponent<?>> getLockedComponents() { private Set<IDIYComponent<?>> getLockedComponents() {
lockedComponents.clear(); lockedComponents.clear();
for (IDIYComponent<?> component : currentProject.getComponents()) { for (IDIYComponent<?> component : currentProject.getComponents()) {