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-2007 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.visualweb.web.ui.dt.component;
042:
043: import com.sun.rave.designtime.DesignBean;
044: import com.sun.rave.designtime.DesignContext;
045: import com.sun.rave.designtime.DesignProperty;
046: import com.sun.rave.designtime.DisplayAction;
047: import com.sun.rave.designtime.Result;
048: import com.sun.rave.designtime.ext.componentgroup.ColorWrapper;
049: import com.sun.rave.designtime.ext.componentgroup.ComponentGroup;
050: import com.sun.rave.designtime.ext.componentgroup.ComponentGroupHolder;
051: import com.sun.rave.designtime.ext.componentgroup.ComponentGroupDesignInfo;
052: import com.sun.rave.designtime.ext.componentgroup.ComponentSubset;
053: import com.sun.rave.designtime.ext.componentgroup.util.ComponentGroupHelper;
054: import com.sun.rave.designtime.ext.componentgroup.impl.ColorWrapperImpl;
055: import com.sun.rave.designtime.ext.componentgroup.impl.ComponentGroupImpl;
056: import com.sun.rave.designtime.ext.componentgroup.impl.ComponentSubsetImpl;
057: import com.sun.rave.web.ui.component.Form;
058: import com.sun.rave.web.ui.component.Form.VirtualFormDescriptor;
059: import java.awt.Color;
060: import java.util.ArrayList;
061: import java.util.List;
062: import java.util.Locale;
063: import java.util.ResourceBundle;
064: import org.netbeans.modules.visualweb.web.ui.dt.AbstractDesignInfo;
065: import javax.faces.component.NamingContainer;
066: import javax.faces.component.UIComponent;
067: import org.netbeans.modules.visualweb.web.ui.dt.component.vforms.VirtualFormsHelper;
068:
069: /**
070: * DesignInfo for the {@link org.netbeans.modules.visualweb.web.ui.dt.component.Form} component.
071: *
072: * @author mbohm
073: * @author gjmurphy
074: */
075: public class FormDesignInfo extends AbstractDesignInfo implements
076: ComponentGroupDesignInfo {
077:
078: /**
079: * <p>The name for any <code>ComponentGroupHolder</code> that holds virtual forms.</p>
080: */
081: public static final String VIRTUAL_FORM_HOLDER_NAME = Form.class
082: .getName(); //NOI18N
083: /**
084: * <p><code>String</code> version of the <code>NamingContainer.SEPARATOR_CHAR</code>, used in qualified ids.</p>
085: */
086: private static final String ID_SEP = String
087: .valueOf(NamingContainer.SEPARATOR_CHAR);
088: /**
089: * <p>The component subset names in a component group representing a virtual form.</p>
090: */
091: private static final String[] SUBSET_NAMES = { "participants",
092: "submitters" }; // NOI18N
093: /**
094: * <p>The line types corresponding to the subset names.</p>
095: */
096: private static final ComponentSubset.LineType[] SUBSET_LINE_TYPES = {
097: ComponentSubset.LineType.SOLID,
098: ComponentSubset.LineType.DASHED };
099:
100: /** Creates a new instance of FormDesignInfo */
101: public FormDesignInfo() {
102: super (Form.class);
103: }
104:
105: /**
106: * Allow form anywhere, so long as parent is not a form and the parent has
107: * no form ancestor.
108: */
109: public boolean acceptParent(DesignBean parentBean,
110: DesignBean childBean, Class childClass) {
111: DesignBean this Bean = parentBean;
112: while (this Bean.getBeanParent() != null) {
113: if (this Bean.getInstance() instanceof Form)
114: return false;
115: this Bean = this Bean.getBeanParent();
116: }
117: return super .isSunWebUIContext(parentBean);
118: }
119:
120: /**
121: * <p>Designtime version of
122: * <code>Form.getFullyQualifiedId(UIComponent)</code> for webui.
123: */
124: /*
125: * Be sure to keep this method in sync with the versions in
126: * <code>org.netbeans.modules.visualweb.web.ui.dt.component.Form</code> (in webui) and
127: * <code>javax.faces.component.html.HtmlFormDesignInfo</code>
128: * (in jsfcl).</p>
129: */
130: public static String getFullyQualifiedId(DesignBean bean) {
131: if (bean == null) {
132: return null;
133: }
134: Object beanInstance = bean.getInstance();
135: if (!(beanInstance instanceof UIComponent)) {
136: return null;
137: }
138: if (beanInstance instanceof Form) {
139: return ID_SEP;
140: }
141: String compId = bean.getInstanceName();
142: if (compId == null) {
143: return null;
144: }
145: StringBuffer sb = new StringBuffer(compId);
146: DesignBean currentBean = bean.getBeanParent();
147: boolean formEncountered = false;
148: while (currentBean != null) {
149: Object currentBeanInstance = currentBean.getInstance();
150: if (currentBeanInstance instanceof UIComponent) {
151: sb.insert(0, ID_SEP);
152: if (currentBeanInstance instanceof Form) {
153: formEncountered = true;
154: break;
155: } else {
156: String currentCompId = currentBean
157: .getInstanceName();
158: if (currentCompId == null) {
159: return null;
160: }
161: sb.insert(0, currentCompId);
162: }
163: }
164: currentBean = currentBean.getBeanParent();
165: }
166: if (formEncountered) {
167: return sb.toString();
168: } else {
169: return null;
170: }
171: }
172:
173: public ComponentGroupHolder[] getComponentGroupHolders() {
174: return new ComponentGroupHolder[] { new VirtualFormHolder() };
175: }
176:
177: /**
178: * <p>A <code>ComponentGroupHolder</code> implementation representing
179: * the virtual forms on the page. The registered instance will be used
180: * by the designer when painting component group borders and legends.</p>
181: */
182: private static class VirtualFormHolder implements
183: ComponentGroupHolder {
184: private static ResourceBundle bundle = ResourceBundle
185: .getBundle(
186: "org.netbeans.modules.visualweb.web.ui.dt.component.Bundle-DT",
187: Locale.getDefault(), VirtualFormHolder.class
188: .getClassLoader());
189:
190: /**
191: * <p>Get the name of the holder.</p>
192: */
193: public String getName() {
194: return VIRTUAL_FORM_HOLDER_NAME;
195: }
196:
197: /**
198: * <p>Create and return <code>ComponentGroup</code> instances
199: * representing the virtual forms on the page. First, find all
200: * <code>Form</code> components on the page and their respective
201: * virtual form descriptors.
202: * For each descriptor, retrieve the color associated with the virtual
203: * form in question, if one was stored in the context data. Then create
204: * <code>ComponentSubsetImpl</code> instances for the participants and
205: * submitters of the virtual form in question. Finally, use the subset
206: * instances, color, and other information to create a
207: * <code>ComponentGroup</code> for the virtual form in question.</p>
208: */
209: public ComponentGroup[] getComponentGroups(
210: DesignContext dcontext) {
211: DesignBean[] formBeans = dcontext
212: .getBeansOfType(Form.class);
213: if (formBeans == null) {
214: return new ComponentGroup[0];
215: }
216:
217: List<ComponentGroup> groupList = new ArrayList<ComponentGroup>();
218: for (int i = 0; i < formBeans.length; i++) {
219: DesignBean formBean = formBeans[i];
220:
221: if (formBean == null) {
222: continue;
223: }
224:
225: Object formObj = formBean.getInstance();
226: if (!(formObj instanceof Form)) {
227: continue;
228: }
229: Form form = (Form) formObj;
230:
231: VirtualFormDescriptor[] vds = form.getVirtualForms();
232:
233: if ((vds == null) || (vds.length == 0)) {
234: continue;
235: }
236:
237: //get form name
238: DesignProperty idProp = formBean.getProperty("id"); //NOI18N
239:
240: String formName = idProp == null ? "" : (String) idProp
241: .getValue(); //NOI18N
242:
243: for (int v = 0; v < vds.length; v++) {
244: //get group name
245: String vfName = vds[v].getName();
246: if (vfName == null) {
247: continue;
248: }
249:
250: String name = formName + "." + vfName; // name like .virtualForm1 would be ok, but unlikely
251:
252: //get explictly assigned color, if any
253: Color color = null;
254: String holderName = VIRTUAL_FORM_HOLDER_NAME;
255: String key = ComponentGroupHelper
256: .getComponentGroupColorKey(holderName, name);
257: Object o = dcontext.getContextData(key);
258: String vkey = ComponentGroupHolder.VIRTUAL_FORM_COLOR_KEY_PREFIX
259: + name;
260: boolean attemptLegacyKeyConversion = false;
261: if (o == null) {
262: //see if there's an entry using the old "virtualFormColor:" prefix
263: attemptLegacyKeyConversion = true;
264: o = dcontext.getContextData(vkey);
265: }
266: //now retest o
267: if (o instanceof ColorWrapper) {
268: color = ((ColorWrapper) o).getColor();
269: if (color != null) {
270: //o is good, so attempt legacy conversion if appropriate
271: if (attemptLegacyKeyConversion) {
272: dcontext.setContextData(vkey, null);
273: dcontext.setContextData(key, o);
274: }
275: }
276: } else if (o instanceof String) {
277: ColorWrapper cw = new ColorWrapperImpl(
278: (String) o);
279: color = cw.getColor();
280: if (color != null) {
281: dcontext.setContextData(key, cw);
282: //o is good, so attempt legacy conversion if appropriate
283: if (attemptLegacyKeyConversion) {
284: dcontext.setContextData(vkey, null);
285: }
286: }
287: }
288:
289: //get subsets
290: String[] participantArr = vds[v]
291: .getParticipatingIds();
292: String[] submitterArr = vds[v].getSubmittingIds();
293:
294: String[][] subsetArrs = { participantArr,
295: submitterArr };
296:
297: ComponentSubset[] componentSubsets = new ComponentSubset[subsetArrs.length];
298: for (int s = 0; s < subsetArrs.length; s++) {
299: String[] subsetArr = subsetArrs[s];
300: componentSubsets[s] = new ComponentSubsetImpl(
301: SUBSET_NAMES[s], subsetArr,
302: SUBSET_LINE_TYPES[s]);
303: }
304:
305: ComponentGroup group = new VirtualFormGroup(name,
306: color, componentSubsets, vfName);
307: groupList.add(group);
308: }
309: }
310: return groupList.toArray(new ComponentGroup[groupList
311: .size()]);
312: }
313:
314: /**
315: * <p>Get the tooltip for the virtual forms toolbar button in the
316: * designer.</p>
317: */
318: public String getToolTip() {
319: return bundle
320: .getString("Form.ComponentGroupHolder.tooltip"); //NOI18N
321: }
322:
323: /**
324: * <p>Get the label for the virtual forms legend.</p>
325: */
326: public String getLegendLabel() {
327: return bundle
328: .getString("Form.ComponentGroupHolder.legendLabel"); //NOI18N
329: }
330:
331: /**
332: * Get the virtual forms context menu item as a <code>DisplayAction[]</code>
333: * with at most one member.</p>
334: */
335: public DisplayAction[] getDisplayActions(
336: DesignContext dcontext, DesignBean[] dbeans) {
337: DisplayAction virtualFormDisplayAction = null;
338: if (dbeans != null && dbeans.length > 0) {
339: virtualFormDisplayAction = VirtualFormsHelper
340: .getContextItem(dbeans);
341: }
342: if (virtualFormDisplayAction == null && dcontext != null) {
343: virtualFormDisplayAction = VirtualFormsHelper
344: .getContextItem(dcontext);
345: }
346: if (virtualFormDisplayAction != null) {
347: return new DisplayAction[] { virtualFormDisplayAction };
348: }
349: return new DisplayAction[0];
350: }
351: }
352:
353: /**
354: * <p>Extends <code>ComponentGroupImpl</code> to override
355: * <code>getLegendEntryLabel</code>, since the name of a <code>VirtualFormGroup</code>
356: * is <code>formName.vfName</code>, while the legend entry label is simply
357: * the virtual form name.</p>
358: */
359: private static class VirtualFormGroup extends ComponentGroupImpl {
360: private String legendEntryLabel;
361:
362: /**
363: * <p>Constructor that accepts an explicit <code>legendEntryLabel</code>.</p>
364: */
365: public VirtualFormGroup(String name, Color color,
366: ComponentSubset[] componentSubsets,
367: String legendEntryLabel) {
368: super (name, color, componentSubsets);
369: this .legendEntryLabel = legendEntryLabel;
370: }
371:
372: /**
373: * <p>Get the legend entry label. This will simply be the virtual form name.</p>
374: */
375: public String getLegendEntryLabel() {
376: return this.legendEntryLabel;
377: }
378: }
379: }
|