mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-11 01:32:08 +10:00
edit cloud project
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
/**
|
||||
* Entity class for editable properties extracted from component objects. Represents a single
|
||||
@@ -21,9 +23,12 @@ public class PropertyWrapper implements Cloneable {
|
||||
private IPropertyValidator validator;
|
||||
private boolean unique = true;
|
||||
private boolean changed = false;
|
||||
private String additionalOptions;
|
||||
private int sortOrder;
|
||||
private String[] listItems;
|
||||
|
||||
public PropertyWrapper(String name, Class<?> type, String getter, String setter, boolean defaultable,
|
||||
IPropertyValidator validator) {
|
||||
IPropertyValidator validator, String additionalOptions, int sortOrder) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
@@ -31,11 +36,18 @@ public class PropertyWrapper implements Cloneable {
|
||||
this.setter = setter;
|
||||
this.defaultable = defaultable;
|
||||
this.validator = validator;
|
||||
this.additionalOptions = additionalOptions;
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public void readFrom(Object object) throws IllegalArgumentException, IllegalAccessException,
|
||||
InvocationTargetException, SecurityException, NoSuchMethodException {
|
||||
this.value = object.getClass().getMethod(getter).invoke(object);
|
||||
if (additionalOptions.startsWith(EditableProperty.DYNAMIC_LIST)) {
|
||||
String functionName = additionalOptions.substring(EditableProperty.DYNAMIC_LIST.length());
|
||||
Method listMethod = object.getClass().getMethod(functionName);
|
||||
listItems = (String[]) listMethod.invoke(object);
|
||||
}
|
||||
}
|
||||
|
||||
// public void readUniqueFrom(IDIYComponent component)
|
||||
@@ -92,6 +104,22 @@ public class PropertyWrapper implements Cloneable {
|
||||
this.changed = changed;
|
||||
}
|
||||
|
||||
public String getAdditionalOptions() {
|
||||
return additionalOptions;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public String[] getListItems() {
|
||||
return listItems;
|
||||
}
|
||||
|
||||
public void setOptions(String[] listItems) {
|
||||
this.listItems = listItems;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Object clone() throws CloneNotSupportedException {
|
||||
// // Try to invoke clone method on value if possible.
|
||||
@@ -105,7 +133,8 @@ public class PropertyWrapper implements Cloneable {
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
PropertyWrapper clone =
|
||||
new PropertyWrapper(this.name, this.type, this.getter, this.setter, this.defaultable, this.validator);
|
||||
new PropertyWrapper(this.name, this.type, this.getter, this.setter, this.defaultable, this.validator,
|
||||
this.additionalOptions, this.sortOrder);
|
||||
clone.value = this.value;
|
||||
clone.changed = this.changed;
|
||||
clone.unique = this.unique;
|
||||
@@ -116,11 +145,11 @@ public class PropertyWrapper implements Cloneable {
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((additionalOptions == null) ? 0 : additionalOptions.hashCode());
|
||||
result = prime * result + (defaultable ? 1231 : 1237);
|
||||
result = prime * result + ((getter == null) ? 0 : getter.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((setter == null) ? 0 : setter.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -133,6 +162,11 @@ public class PropertyWrapper implements Cloneable {
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PropertyWrapper other = (PropertyWrapper) obj;
|
||||
if (additionalOptions == null) {
|
||||
if (other.additionalOptions != null)
|
||||
return false;
|
||||
} else if (!additionalOptions.equals(other.additionalOptions))
|
||||
return false;
|
||||
if (defaultable != other.defaultable)
|
||||
return false;
|
||||
if (getter == null) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class Project implements Serializable {
|
||||
gridSpacing = DEFAULT_GRID_SPACING;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
@EditableProperty(defaultable = false, sortOrder = 1)
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class Project implements Serializable {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@EditableProperty(sortOrder = 3)
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class Project implements Serializable {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
@EditableProperty(defaultable = false, additionalOptions = EditableProperty.MULTI_LINE, sortOrder = 2)
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class Project implements Serializable {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@EditableProperty(sortOrder = 4)
|
||||
public Size getWidth() {
|
||||
return width;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ public class Project implements Serializable {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@EditableProperty(sortOrder = 5)
|
||||
public Size getHeight() {
|
||||
return height;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public class Project implements Serializable {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Grid spacing", validatorClass = SpacingValidator.class)
|
||||
@EditableProperty(name = "Grid spacing", validatorClass = SpacingValidator.class, sortOrder = 6)
|
||||
public Size getGridSpacing() {
|
||||
return gridSpacing;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,18 @@ import org.diylc.core.IPropertyValidator;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EditableProperty {
|
||||
|
||||
/**
|
||||
* Used to designate that a {@link String} property can have multi-lined text.
|
||||
*/
|
||||
public static final String MULTI_LINE = "MULTI-LINE";
|
||||
/**
|
||||
* Used when property can have one of the values from a dynamic list. In such cases,
|
||||
* {@link EditableProperty#additionalOptions()} should begin with
|
||||
* {@link EditableProperty#DYNAMIC_LIST} and contain a method name from the parent object that
|
||||
* should be called to obtain the {@link String} array with possible options.
|
||||
*/
|
||||
public static final String DYNAMIC_LIST = "DYNAMIC_LIST:";
|
||||
|
||||
/**
|
||||
* Returns property name. If left blank property name will be extracted from the getter name, e.g.
|
||||
* getter <code>getXYZ</code> will induce property name <code>XYZ</code>. <br>
|
||||
@@ -39,4 +51,19 @@ public @interface EditableProperty {
|
||||
* @return
|
||||
*/
|
||||
Class<? extends IPropertyValidator> validatorClass() default AllowAllValidator.class;
|
||||
|
||||
/**
|
||||
* Optional parameter in case we want to force an order of properties.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int sortOrder() default Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Optional parameter for properties that require additional configuration. This will be passed
|
||||
* down to the editor factory.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String additionalOptions() default "";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.diylc.plugins.cloud.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
public class ProjectEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -11,12 +13,15 @@ public class ProjectEntity implements Serializable {
|
||||
private String description;
|
||||
private String owner;
|
||||
private String category;
|
||||
private String categoryForDisplay;
|
||||
private String updated;
|
||||
private String thumbnailUrl;
|
||||
private String downloadUrl;
|
||||
private String keywords;
|
||||
private int viewCount;
|
||||
private int downloadCount;
|
||||
private int commentCount;
|
||||
private String[] categories;
|
||||
|
||||
public ProjectEntity() {
|
||||
super();
|
||||
@@ -30,6 +35,7 @@ public class ProjectEntity implements Serializable {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false, sortOrder = 1)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -38,6 +44,7 @@ public class ProjectEntity implements Serializable {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false, additionalOptions = EditableProperty.MULTI_LINE, sortOrder = 3)
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
@@ -53,7 +60,7 @@ public class ProjectEntity implements Serializable {
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
@@ -61,6 +68,23 @@ public class ProjectEntity implements Serializable {
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false, sortOrder = 2, additionalOptions = EditableProperty.DYNAMIC_LIST + "getCategories")
|
||||
public String getCategoryForDisplay() {
|
||||
return categoryForDisplay;
|
||||
}
|
||||
|
||||
public void setCategoryForDisplay(String categoryForDisplay) {
|
||||
this.categoryForDisplay = categoryForDisplay;
|
||||
}
|
||||
|
||||
public String[] getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void setCategories(String[] categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
public String getUpdated() {
|
||||
return updated;
|
||||
@@ -110,6 +134,15 @@ public class ProjectEntity implements Serializable {
|
||||
this.commentCount = commentCount;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false, sortOrder = 4)
|
||||
public String getKeywords() {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
public void setKeywords(String keywords) {
|
||||
this.keywords = keywords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
@@ -120,6 +153,7 @@ public class ProjectEntity implements Serializable {
|
||||
result = prime * result + downloadCount;
|
||||
result = prime * result + ((downloadUrl == null) ? 0 : downloadUrl.hashCode());
|
||||
result = prime * result + id;
|
||||
result = prime * result + ((keywords == null) ? 0 : keywords.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
|
||||
result = prime * result + ((thumbnailUrl == null) ? 0 : thumbnailUrl.hashCode());
|
||||
@@ -158,6 +192,11 @@ public class ProjectEntity implements Serializable {
|
||||
return false;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
if (keywords == null) {
|
||||
if (other.keywords != null)
|
||||
return false;
|
||||
} else if (!keywords.equals(other.keywords))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
|
||||
@@ -8,14 +8,18 @@ import java.net.NetworkInterface;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.plugins.cloud.model.CommentEntity;
|
||||
import org.diylc.plugins.cloud.model.IServiceAPI;
|
||||
import org.diylc.plugins.cloud.model.ProjectEntity;
|
||||
import org.diylc.plugins.cloud.model.UserEntity;
|
||||
import org.diylc.presenter.ComparatorFactory;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
|
||||
import com.diyfever.httpproxy.PhpFlatProxy;
|
||||
import com.diyfever.httpproxy.ProxyFactory;
|
||||
@@ -153,6 +157,24 @@ public class CloudPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateProjectDetails(ProjectEntity project, String diylcVersion) throws IOException, CloudException {
|
||||
String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null);
|
||||
String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null);
|
||||
|
||||
if (username == null || token == null)
|
||||
throw new CloudException("Login failed. Please try to login again.");
|
||||
|
||||
try {
|
||||
String res =
|
||||
getService().uploadProject(username, token, getMachineId(), project.getName(), project.getCategoryForDisplay(),
|
||||
project.getDescription(), diylcVersion, project.getKeywords(), null, null, project.getId());
|
||||
if (!res.equals(SUCCESS))
|
||||
throw new CloudException(res);
|
||||
} catch (Exception e) {
|
||||
throw new CloudException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteProject(int projectId) throws CloudException {
|
||||
String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null);
|
||||
String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null);
|
||||
@@ -282,14 +304,15 @@ public class CloudPresenter {
|
||||
LOG.info("Received " + projects.size() + " results. Downloading thumbnails...");
|
||||
// Download thumbnails and replace urls with local paths to speed up loading in the main
|
||||
// thread
|
||||
for (int i = 0; i < projects.size(); i++) {
|
||||
String url = projects.get(i).getThumbnailUrl();
|
||||
for (ProjectEntity project : projects) {
|
||||
String url = project.getThumbnailUrl();
|
||||
URL website = new URL(url);
|
||||
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
|
||||
File temp = File.createTempFile("thumbnail", ".png");
|
||||
FileOutputStream fos = new FileOutputStream(temp);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
projects.get(i).setThumbnailUrl(temp.getAbsolutePath());
|
||||
project.setThumbnailUrl(temp.getAbsolutePath());
|
||||
project.setCategories(getCategories());
|
||||
fos.close();
|
||||
}
|
||||
LOG.info("Finished downloading thumbnails.");
|
||||
@@ -324,6 +347,20 @@ public class CloudPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
public List<PropertyWrapper> getProjectProperties(ProjectEntity project) {
|
||||
List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties(ProjectEntity.class);
|
||||
try {
|
||||
for (PropertyWrapper property : properties) {
|
||||
property.readFrom(project);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not get project entity properties", e);
|
||||
return null;
|
||||
}
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getDefaultPropertyComparator());
|
||||
return properties;
|
||||
}
|
||||
|
||||
private String getMachineId() {
|
||||
if (machineId == null) {
|
||||
try {
|
||||
|
||||
@@ -67,6 +67,27 @@ public class ComparatorFactory {
|
||||
return propertyNameComparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a comparator that compares properties by sort order and then by name
|
||||
* @return
|
||||
*/
|
||||
public Comparator<PropertyWrapper> getDefaultPropertyComparator() {
|
||||
if (propertyNameComparator == null) {
|
||||
propertyNameComparator = new Comparator<PropertyWrapper>() {
|
||||
|
||||
@Override
|
||||
public int compare(PropertyWrapper o1, PropertyWrapper o2) {
|
||||
int comp = new Integer(o1.getSortOrder()).compareTo(o2.getSortOrder());
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
return propertyNameComparator;
|
||||
}
|
||||
|
||||
public Comparator<IDIYComponent<?>> getComponentZOrderComparator() {
|
||||
if (componentZOrderComparator == null) {
|
||||
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@@ -154,7 +154,7 @@ public class ComponentProcessor {
|
||||
Method setter = clazz.getMethod("set" + method.getName().substring(3), method.getReturnType());
|
||||
PropertyWrapper property =
|
||||
new PropertyWrapper(name, method.getReturnType(), method.getName(), setter.getName(),
|
||||
annotation.defaultable(), validator);
|
||||
annotation.defaultable(), validator, annotation.additionalOptions(), annotation.sortOrder());
|
||||
properties.add(property);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
@@ -228,7 +228,7 @@ public class ComponentProcessor {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getPropertyNameComparator());
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getDefaultPropertyComparator());
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -1691,7 +1691,7 @@ public class Presenter implements IPlugInPort {
|
||||
LOG.error("Could not get project properties", e);
|
||||
return null;
|
||||
}
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getPropertyNameComparator());
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getDefaultPropertyComparator());
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user