blob: ed83a56244a1a2abdcd914d8748cce079d8c07eb [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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 com.intellij.uiDesigner.clientProperties;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* @author yole
*/
public class ClientPropertiesManager extends AbstractProjectComponent implements JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.clientProperties.ClientPropertiesManager");
@NonNls private static final String ELEMENT_PROPERTIES = "properties";
@NonNls private static final String ELEMENT_PROPERTY = "property";
@NonNls private static final String ATTRIBUTE_CLASS = "class";
@NonNls private static final String ATTRIBUTE_NAME = "name";
@NonNls private static final String COMPONENT_NAME = "ClientPropertiesManager";
public static ClientPropertiesManager getInstance(final Project project) {
return project.getComponent(ClientPropertiesManager.class);
}
private static ClientPropertiesManager ourDefaultManager;
private final Map<String, List<ClientProperty>> myPropertyMap = new TreeMap<String, List<ClientProperty>>();
public ClientPropertiesManager() {
super(null);
}
private ClientPropertiesManager(final Map<String, List<ClientProperty>> propertyMap) {
this();
myPropertyMap.putAll(propertyMap);
}
public ClientPropertiesManager clone() {
return new ClientPropertiesManager(myPropertyMap);
}
public void saveFrom(final ClientPropertiesManager manager) {
myPropertyMap.clear();
myPropertyMap.putAll(manager.myPropertyMap);
}
public void projectOpened() {
checkInitDefaultManager();
}
private static void checkInitDefaultManager() {
if (ourDefaultManager == null) {
ourDefaultManager = new ClientPropertiesManager();
try {
//noinspection HardCodedStringLiteral
final Document document = new SAXBuilder().build(ClientPropertiesManager.class.getResource("/" + COMPONENT_NAME + ".xml"));
final Element child = document.getRootElement();
ourDefaultManager.readExternal(child);
}
catch (Exception e) {
LOG.error(e);
}
}
}
@NotNull @NonNls
public String getComponentName() {
return COMPONENT_NAME;
}
public static class ClientProperty implements Comparable {
private final String myName;
private final String myClass;
public ClientProperty(final String name, final String aClass) {
myName = name;
myClass = aClass;
}
public String getName() {
return myName;
}
public String getValueClass() {
return myClass;
}
public int compareTo(final Object o) {
ClientProperty prop = (ClientProperty) o;
return myName.compareTo(prop.getName());
}
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ClientProperty that = (ClientProperty)o;
if (!myClass.equals(that.myClass)) return false;
if (!myName.equals(that.myName)) return false;
return true;
}
public int hashCode() {
int result;
result = myName.hashCode();
result = 31 * result + myClass.hashCode();
return result;
}
}
public void readExternal(Element element) throws InvalidDataException {
myPropertyMap.clear();
for(Object o: element.getChildren(ELEMENT_PROPERTIES)) {
Element propertiesElement = (Element) o;
String aClass = propertiesElement.getAttributeValue(ATTRIBUTE_CLASS);
List<ClientProperty> classProps = new ArrayList<ClientProperty>();
for(Object p: propertiesElement.getChildren(ELEMENT_PROPERTY)) {
Element propertyElement = (Element) p;
String propName = propertyElement.getAttributeValue(ATTRIBUTE_NAME);
String propClass = propertyElement.getAttributeValue(ATTRIBUTE_CLASS);
classProps.add(new ClientProperty(propName, propClass));
}
myPropertyMap.put(aClass, classProps);
}
}
public void writeExternal(Element element) throws WriteExternalException {
if (equals(ourDefaultManager)) {
throw new WriteExternalException();
}
for(Map.Entry<String, List<ClientProperty>> entry: myPropertyMap.entrySet()) {
Element propertiesElement = new Element(ELEMENT_PROPERTIES);
propertiesElement.setAttribute(ATTRIBUTE_CLASS, entry.getKey());
for(ClientProperty prop: entry.getValue()) {
Element propertyElement = new Element(ELEMENT_PROPERTY);
propertyElement.setAttribute(ATTRIBUTE_NAME, prop.getName());
propertyElement.setAttribute(ATTRIBUTE_CLASS, prop.getValueClass());
propertiesElement.addContent(propertyElement);
}
element.addContent(propertiesElement);
}
}
public void addConfiguredProperty(final Class selectedClass, final ClientProperty enteredProperty) {
List<ClientProperty> list = myPropertyMap.get(selectedClass.getName());
if (list == null) {
list = new ArrayList<ClientProperty>();
myPropertyMap.put(selectedClass.getName(), list);
}
list.add(enteredProperty);
}
public void removeConfiguredProperty(final Class selectedClass, final String name) {
List<ClientProperty> list = myPropertyMap.get(selectedClass.getName());
if (list != null) {
for(ClientProperty prop: list) {
if (prop.getName().equals(name)) {
list.remove(prop);
break;
}
}
}
}
public List<Class> getConfiguredClasses() {
List<Class> result = new ArrayList<Class>();
for(String className: myPropertyMap.keySet()) {
try {
result.add(Class.forName(className));
}
catch (ClassNotFoundException e) {
// TODO: do something better than ignore?
}
}
return result;
}
public void addClientPropertyClass(final String className) {
if (!myPropertyMap.containsKey(className)) {
myPropertyMap.put(className, new ArrayList<ClientProperty>());
}
}
public void removeClientPropertyClass(final Class selectedClass) {
myPropertyMap.remove(selectedClass.getName());
}
public ClientProperty[] getConfiguredProperties(Class componentClass) {
final List<ClientProperty> list = myPropertyMap.get(componentClass.getName());
if (list == null) return new ClientProperty[0];
return list.toArray(new ClientProperty[list.size()]);
}
public ClientProperty[] getClientProperties(Class componentClass) {
ArrayList<ClientProperty> result = new ArrayList<ClientProperty>();
while(!componentClass.getName().equals(Object.class.getName())) {
List<ClientProperty> props = myPropertyMap.get(componentClass.getName());
if (props != null) {
result.addAll(props);
}
componentClass = componentClass.getSuperclass();
}
Collections.sort(result);
return result.toArray(new ClientProperty[result.size()]);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ClientPropertiesManager)) {
return false;
}
ClientPropertiesManager rhs = (ClientPropertiesManager) obj;
if (rhs.myPropertyMap.size() != myPropertyMap.size()) {
return false;
}
for(Map.Entry<String, List<ClientProperty>> entry: myPropertyMap.entrySet()) {
List<ClientProperty> rhsList = rhs.myPropertyMap.get(entry.getKey());
if (rhsList == null || rhsList.size() != entry.getValue().size()) {
return false;
}
for(ClientProperty prop: entry.getValue()) {
if (!rhsList.contains(prop)) {
return false;
}
}
}
return true;
}
}