001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.vmd.midp.components;
042:
043: import org.netbeans.modules.vmd.api.model.*;
044: import org.netbeans.modules.vmd.api.model.common.DocumentSupport;
045: import org.netbeans.modules.vmd.midp.components.categories.CommandsCategoryCD;
046: import org.netbeans.modules.vmd.midp.components.categories.ControllersCategoryCD;
047: import org.netbeans.modules.vmd.midp.components.commands.CommandCD;
048: import org.netbeans.modules.vmd.midp.components.displayables.DisplayableCD;
049: import org.netbeans.modules.vmd.midp.components.general.ClassCD;
050: import org.netbeans.modules.vmd.midp.components.general.RootCD;
051: import org.netbeans.modules.vmd.midp.components.handlers.EventHandlerCD;
052: import org.netbeans.modules.vmd.midp.components.handlers.SwitchDisplayableEventHandlerCD;
053: import org.netbeans.modules.vmd.midp.components.items.ItemCD;
054: import org.netbeans.modules.vmd.midp.components.sources.CommandEventSourceCD;
055: import org.netbeans.modules.vmd.midp.components.sources.EventSourceCD;
056: import org.netbeans.modules.vmd.midp.components.sources.ItemCommandEventSourceCD;
057: import org.netbeans.modules.vmd.midp.general.AbstractEventHandlerCreatorPresenter;
058:
059: import java.util.*;
060:
061: /**
062: * @author David Kaspar
063: */
064: public final class MidpDocumentSupport {
065:
066: public static final String PROJECT_TYPE_MIDP = "vmd-midp"; // NOI18N
067:
068: public static final Comparator<DesignComponent> COMPONENT_DISPLAY_NAME_COMPARATOR = new Comparator<DesignComponent>() {
069: public int compare(DesignComponent component1,
070: DesignComponent component2) {
071: String name1 = (String) component1.readProperty(
072: ClassCD.PROP_INSTANCE_NAME).getPrimitiveValue();
073: String name2 = (String) component2.readProperty(
074: ClassCD.PROP_INSTANCE_NAME).getPrimitiveValue();
075: if (name1 == null)
076: return -1;
077: else if (name2 == null)
078: return 1;
079:
080: return name1.compareTo(name2);
081: }
082: };
083:
084: public static DesignComponent getCategoryComponent(
085: DesignDocument document, TypeID categoryType) {
086: List<DesignComponent> list = DocumentSupport
087: .gatherSubComponentsOfType(document.getRootComponent(),
088: categoryType);
089: if (list.size() == 0
090: && document.getTransactionManager().isWriteAccess()) {
091: DesignComponent categoryComponent = document
092: .createComponent(categoryType);
093: document.getRootComponent().addComponent(categoryComponent);
094: return categoryComponent;
095: }
096: assert list.size() == 1;
097: return list.get(0);
098: }
099:
100: public static DesignComponent getSingletonCommand(
101: final DesignDocument document, final TypeID typeID) {
102: final DesignComponent categoryComponent = getCategoryComponent(
103: document, CommandsCategoryCD.TYPEID);
104:
105: assert categoryComponent != null;
106: List<DesignComponent> list = DocumentSupport
107: .gatherSubComponentsOfType(categoryComponent, typeID);
108: if (list.size() == 1)
109: return list.get(0);
110: else if (list.size() == 0) {
111: DesignComponent newComponent = document
112: .createComponent(typeID);
113: categoryComponent.addComponent(newComponent);
114: return newComponent;
115: }
116:
117: throw new IllegalStateException("Component " + typeID
118: + " should be singelton per document"); //NOI18N;
119: }
120:
121: public static DesignComponent attachCommandToDisplayable(
122: DesignComponent displayable, DesignComponent command) {
123: DesignComponent source = displayable.getDocument()
124: .createComponent(CommandEventSourceCD.TYPEID);
125: MidpDocumentSupport.addEventSource(displayable,
126: DisplayableCD.PROP_COMMANDS, source);
127:
128: source.writeProperty(CommandEventSourceCD.PROP_DISPLAYABLE,
129: PropertyValue.createComponentReference(displayable));
130: source.writeProperty(CommandEventSourceCD.PROP_COMMAND,
131: PropertyValue.createComponentReference(command));
132:
133: return source;
134: }
135:
136: public static DesignComponent attachCommandToItem(
137: DesignComponent item, DesignComponent command) {
138: DesignComponent itemCommandEventSource = command.getDocument()
139: .createComponent(ItemCommandEventSourceCD.TYPEID);
140: itemCommandEventSource.writeProperty(
141: ItemCommandEventSourceCD.PROP_COMMAND, PropertyValue
142: .createComponentReference(command));
143: itemCommandEventSource.writeProperty(
144: ItemCommandEventSourceCD.PROP_ITEM, PropertyValue
145: .createComponentReference(item));
146: MidpArraySupport.append(item, ItemCD.PROP_COMMANDS,
147: itemCommandEventSource);
148: item.addComponent(itemCommandEventSource);
149: return itemCommandEventSource;
150: }
151:
152: public static void addEventSource(DesignComponent component,
153: String propertyName, DesignComponent eventSource) {
154: component.addComponent(eventSource);
155: PropertyValue sources = component.readProperty(propertyName);
156: sources = PropertyValueSupport.addArrayValue(sources,
157: PropertyValue.createComponentReference(eventSource));
158: component.writeProperty(propertyName, sources);
159: }
160:
161: // // TODO - PropertyValue.equals is not implemented -> it is not working!
162: // public static void removeEventSource (DesignComponent component, String propertyName, DesignComponent eventSource) {
163: // PropertyValue sources = component.readProperty (propertyName);
164: // PropertyValueSupport.removeArrayValue (sources, PropertyValue.createComponentReference (eventSource));
165: // component.writeProperty (propertyName, sources);
166: // component.removeComponent (eventSource);
167: // }
168:
169: public static boolean isCreatableEventHandlerTo(
170: DesignComponent targetComponent) {
171: return targetComponent == null
172: || targetComponent
173: .getPresenter(AbstractEventHandlerCreatorPresenter.class) != null;
174: }
175:
176: public static DesignComponent updateEventHandlerFromTarget(
177: DesignComponent eventSource, DesignComponent targetComponent) {
178: assert targetComponent == null
179: || !targetComponent.getDocument()
180: .getDescriptorRegistry().isInHierarchy(
181: EventHandlerCD.TYPEID,
182: targetComponent.getType());
183: DesignComponent oldEventHandler = eventSource.readProperty(
184: EventSourceCD.PROP_EVENT_HANDLER).getComponent();
185: AbstractEventHandlerCreatorPresenter targetPresenter = targetComponent != null ? targetComponent
186: .getPresenter(AbstractEventHandlerCreatorPresenter.class)
187: : null;
188: DesignComponent newEventHandler = targetPresenter != null ? targetPresenter
189: .createReuseEventHandler(eventSource, oldEventHandler,
190: targetComponent)
191: : null;
192: return updateEventHandlerWithNew(eventSource, newEventHandler);
193: }
194:
195: public static DesignComponent updateEventHandlerWithNew(
196: DesignComponent eventSource, DesignComponent newEventHandler) {
197: // System.out.println(eventSource + " " + newEventHandler);
198: assert newEventHandler == null
199: || newEventHandler.getDocument()
200: .getDescriptorRegistry().isInHierarchy(
201: EventHandlerCD.TYPEID,
202: newEventHandler.getType());
203: DesignComponent oldEventHandler = eventSource.readProperty(
204: EventSourceCD.PROP_EVENT_HANDLER).getComponent();
205: if (oldEventHandler == newEventHandler)
206: return oldEventHandler;
207: if (oldEventHandler != null) {
208: oldEventHandler.writeProperty(
209: EventHandlerCD.PROP_EVENT_SOURCE, PropertyValue
210: .createNull());
211: oldEventHandler.removeFromParentComponent();
212: }
213: if (newEventHandler != null) {
214: eventSource.addComponent(newEventHandler);
215: eventSource.writeProperty(EventSourceCD.PROP_EVENT_HANDLER,
216: PropertyValue
217: .createComponentReference(newEventHandler));
218: newEventHandler.writeProperty(
219: EventHandlerCD.PROP_EVENT_SOURCE, PropertyValue
220: .createComponentReference(eventSource));
221: } else {
222: eventSource.writeProperty(EventSourceCD.PROP_EVENT_HANDLER,
223: PropertyValue.createNull());
224: }
225: return newEventHandler;
226: }
227:
228: public static void updateEventHandlerWithAlert(
229: DesignComponent eventHandler, DesignComponent alert) {
230: if (alert != null) {
231: eventHandler.writeProperty(
232: SwitchDisplayableEventHandlerCD.PROP_ALERT,
233: PropertyValue.createComponentReference(alert));
234: } else {
235: eventHandler.writeProperty(
236: SwitchDisplayableEventHandlerCD.PROP_ALERT,
237: PropertyValue.createNull());
238: }
239: }
240:
241: public static void updateSwitchDisplayableEventHandler(
242: DesignComponent eventHandler, DesignComponent alert,
243: DesignComponent displayable) {
244: eventHandler.writeProperty(
245: SwitchDisplayableEventHandlerCD.PROP_DISPLAYABLE,
246: PropertyValue.createComponentReference(displayable));
247: updateEventHandlerWithAlert(eventHandler, alert);
248: }
249:
250: public static String createDisplayNameFromTypeID(TypeID type) {
251: String str = type.getString();
252: int i = str.lastIndexOf('.');
253: return i >= 0 ? str.substring(i + 1) : str;
254: }
255:
256: public static Collection<DesignComponent> getAvailableCommandsForComponent(
257: DesignComponent component) {
258: Collection<DesignComponent> componentsUnderCommandCategory = getCategoryComponent(
259: component.getDocument(), CommandsCategoryCD.TYPEID)
260: .getComponents();
261: DescriptorRegistry registry = component.getDocument()
262: .getDescriptorRegistry();
263: List<DesignComponent> unusedCommands = null;
264: Set<DesignComponent> usedCommands = null;
265:
266: for (PropertyValue propertyValue : component.readProperty(
267: DisplayableCD.PROP_COMMANDS).getArray()) {
268: DesignComponent currentComponent = propertyValue
269: .getComponent();
270: if (currentComponent == null)
271: continue;
272: if (usedCommands == null)
273: usedCommands = new HashSet<DesignComponent>();
274: usedCommands.add(currentComponent.readProperty(
275: CommandEventSourceCD.PROP_COMMAND).getComponent());
276: }
277: for (DesignComponent componentChild : componentsUnderCommandCategory) {
278: if (usedCommands != null
279: && usedCommands.contains(componentChild))
280: continue;
281: if (registry.isInHierarchy(CommandCD.TYPEID, componentChild
282: .getType())
283: && (Boolean) componentChild.readProperty(
284: CommandCD.PROP_ORDINARY)
285: .getPrimitiveValue()) {
286: if (unusedCommands == null)
287: unusedCommands = new ArrayList<DesignComponent>();
288: unusedCommands.add(componentChild);
289: }
290: }
291: if (unusedCommands != null)
292: Collections.sort(unusedCommands,
293: COMPONENT_DISPLAY_NAME_COMPARATOR);
294:
295: return unusedCommands;
296: }
297:
298: public static DesignComponent getCommandListener(
299: DesignDocument document, TypeID listenerType) {
300: DesignComponent controllersCategory = getCategoryComponent(
301: document, ControllersCategoryCD.TYPEID);
302: List<DesignComponent> list = DocumentSupport
303: .gatherSubComponentsOfType(controllersCategory,
304: listenerType);
305: if (list.isEmpty()) {
306: DesignComponent commandListener = document
307: .createComponent(listenerType);
308: controllersCategory.addComponent(commandListener);
309: return commandListener;
310: }
311: assert list.size() == 1;
312: return list.get(0);
313: }
314:
315: public static int getMidpVersion(DesignDocument document) {
316: PropertyValue propertyValue = document.getRootComponent()
317: .readProperty(RootCD.PROP_VERSION);
318: return propertyValue.getKind() == PropertyValue.Kind.VALUE
319: && RootCD.VALUE_MIDP_2_0.equals(MidpTypes
320: .getString(propertyValue)) ? 2 : 1; // NOI18N
321: }
322:
323: }
|