1/*******************************************************************************
2 * Copyright (c) 2011 Google, Inc.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Google, Inc. - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.wb.internal.core.model.property;
12
13import com.google.common.collect.Maps;
14
15import org.eclipse.wb.internal.core.model.property.category.PropertyCategory;
16import org.eclipse.wb.internal.core.model.property.editor.PropertyEditor;
17
18import java.util.Comparator;
19import java.util.Map;
20
21/**
22 * {@link Property} is used to display/change properties of ObjectInfo's.
23 *
24 * @author scheglov_ke
25 * @coverage core.model.property
26 */
27public abstract class Property {
28  /**
29   * The value that should be used when we don't know real value of {@link Property}. We can not use
30   * <code>null</code> because <code>null</code> can be valid value.
31   */
32  public static final Object UNKNOWN_VALUE = new Object() {
33    @Override
34    public String toString() {
35      return "UNKNOWN_VALUE";
36    }
37  };
38  ////////////////////////////////////////////////////////////////////////////
39  //
40  // Instance fields
41  //
42  ////////////////////////////////////////////////////////////////////////////
43  protected final PropertyEditor m_editor;
44
45  ////////////////////////////////////////////////////////////////////////////
46  //
47  // Constructor
48  //
49  ////////////////////////////////////////////////////////////////////////////
50  public Property(PropertyEditor editor) {
51    m_category = PropertyCategory.NORMAL;
52    m_editor = editor;
53  }
54
55  ////////////////////////////////////////////////////////////////////////////
56  //
57  // Presentation
58  //
59  ////////////////////////////////////////////////////////////////////////////
60  /**
61   * @return the title displayed to the user to identify the property.
62   */
63  public abstract String getTitle();
64
65  /**
66   * @return <code>true</code> if this property has a non-default value
67   */
68  public abstract boolean isModified() throws Exception;
69
70  ////////////////////////////////////////////////////////////////////////////
71  //
72  // Category
73  //
74  ////////////////////////////////////////////////////////////////////////////
75  private PropertyCategory m_category;
76
77  /**
78   * @return current {@link PropertyCategory}.
79   */
80  public final PropertyCategory getCategory() {
81    return m_category;
82  }
83
84  /**
85   * Sets the {@link PropertyCategory} for this {@link Property}.
86   */
87  public final void setCategory(PropertyCategory category) {
88    m_category = category;
89  }
90
91  ////////////////////////////////////////////////////////////////////////////
92  //
93  // Value
94  //
95  ////////////////////////////////////////////////////////////////////////////
96  /**
97   * @return the current value of this {@link Property} or {@link #UNKNOWN_VALUE}.
98   */
99  public abstract Object getValue() throws Exception;
100
101  /**
102   * Sets the new value of this {@link Property}.
103   *
104   * @param the
105   *          new value of {@link Property} or {@link #UNKNOWN_VALUE} if {@link Property}
106   *          modification should be removed.
107   */
108  public abstract void setValue(Object value) throws Exception;
109
110  ////////////////////////////////////////////////////////////////////////////
111  //
112  // Editor
113  //
114  ////////////////////////////////////////////////////////////////////////////
115  /**
116   * @return the {@link PropertyEditor}.
117   */
118  public final PropertyEditor getEditor() {
119    return m_editor;
120  }
121
122  ////////////////////////////////////////////////////////////////////////////
123  //
124  // Composite
125  //
126  ////////////////////////////////////////////////////////////////////////////
127  /**
128   * @return the composite {@link Property} for given array of {@link Property}'s or
129   *         <code>null</code> if no composite {@link Property} can be created.
130   */
131  public Property getComposite(Property[] properties) {
132    return null;
133  }
134
135  public <T> T getAdapter(Class<T> adapter) {
136    return null;
137  }
138
139  ////////////////////////////////////////////////////////////////////////////
140  //
141  // Arbitrary values map
142  //
143  ////////////////////////////////////////////////////////////////////////////
144  private Map<Object, Object> m_arbitraryMap;
145
146  /**
147   * Associates the given value with the given key.
148   */
149  public final void putArbitraryValue(Object key, Object value) {
150    if (m_arbitraryMap == null) {
151      m_arbitraryMap = Maps.newHashMap();
152    }
153    m_arbitraryMap.put(key, value);
154  }
155
156  /**
157   * @return the value to which the given key is mapped, or <code>null</code>.
158   */
159  public final Object getArbitraryValue(Object key) {
160    if (m_arbitraryMap != null) {
161      return m_arbitraryMap.get(key);
162    }
163    return null;
164  }
165
166  /**
167   * Removes the mapping for a key.
168   */
169  public final void removeArbitraryValue(Object key) {
170    if (m_arbitraryMap != null) {
171      m_arbitraryMap.remove(key);
172    }
173  }
174
175  // BEGIN ADT MODIFICATIONS
176
177    /**
178     * Returns the name of the property (which is not always the same as the
179     * title; for example, the "maxWidth" property has title "Max Width" and
180     * name "maxWidth".
181     * <p>
182     * This is shown in tooltips to users etc to make it clear what they should
183     * use in their own code.
184     *
185     * @return the name of the property
186     */
187  public String getName() {
188      return getTitle();
189  }
190
191  private int mPriority;
192
193  /**
194   * Gets the custom sort priority of this property
195   *
196   * @return the sort priority
197   */
198  public int getPriority() {
199      return mPriority;
200  }
201
202  /**
203   * Sets the custom sort priority of this property
204   *
205   * @param priority the new priority to use
206   */
207  public void setPriority(int priority) {
208      this.mPriority = priority;
209  }
210
211  /** Sort {@link Property} instances alphabetically by property name */
212  public static final Comparator<Property> ALPHABETICAL = new Comparator<Property>() {
213      @Override
214      public int compare(Property p1, Property p2) {
215          return p1.getName().compareTo(p2.getName());
216      }
217  };
218
219  /** Sort {@link Property} instances by priority */
220  public static final Comparator<Property> PRIORITY = new Comparator<Property>() {
221      @Override
222      public int compare(Property p1, Property p2) {
223          int delta = p1.mPriority - p2.mPriority;
224          if (delta != 0) {
225              return delta;
226          }
227
228          return p1.getName().compareTo(p2.getName());
229      }
230  };
231  // END ADT MODIFICATIONS
232}
233