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.faces.dt.component.html;
042:
043: import com.sun.rave.designtime.*;
044: import org.netbeans.modules.visualweb.faces.dt.HtmlDesignInfoBase;
045: import javax.faces.component.NamingContainer;
046: import javax.faces.component.UIComponent;
047: import java.io.Serializable;
048: import java.util.StringTokenizer;
049: import java.util.List;
050: import java.util.ArrayList;
051: import javax.faces.component.UIForm;
052: import javax.faces.component.html.HtmlForm;
053:
054: public class HtmlFormDesignInfo extends HtmlDesignInfoBase {
055:
056: private static final String ID_SEP = String
057: .valueOf(NamingContainer.SEPARATOR_CHAR);
058: private static final String ID_WILD = String.valueOf("*"); //NOI18N
059: private static final String VF_DELIM_1 = ","; //NOI18N
060: private static final String VF_DELIM_2 = "|"; //NOI18N
061:
062: public Class getBeanClass() {
063: return HtmlForm.class;
064: }
065:
066: public DisplayAction[] getContextItems(DesignBean lbean) {
067: return null;
068: }
069:
070: public boolean acceptLink(DesignBean targetBean,
071: DesignBean sourceBean, Class sourceClass) {
072: return false;
073: }
074:
075: public Result linkBeans(DesignBean targetBean, DesignBean sourceBean) {
076: return null;
077: }
078:
079: /**
080: * <p>Designtime version of
081: * <code>Form.getFullyQualifiedId(UIComponent)</code> for jsfcl.
082: */
083: /*
084: * Be sure to keep this method in sync with the versions in
085: * <code>com.sun.rave.web.ui.component.Form</code> (in webui) and
086: * <code>com.sun.rave.web.ui.component.FormDesignInfo</code>
087: * (in webui).</p>
088: */
089: public static String getFullyQualifiedId(DesignBean bean) {
090: if (bean == null) {
091: return null;
092: }
093: Object beanInstance = bean.getInstance();
094: if (!(beanInstance instanceof UIComponent)) {
095: return null;
096: }
097: if (beanInstance instanceof UIForm) {
098: return ID_SEP;
099: }
100: String compId = bean.getInstanceName();
101: if (compId == null) {
102: return null;
103: }
104: StringBuffer sb = new StringBuffer(compId);
105: DesignBean currentBean = bean.getBeanParent();
106: boolean formEncountered = false;
107: while (currentBean != null) {
108: Object currentBeanInstance = currentBean.getInstance();
109: if (currentBeanInstance instanceof UIComponent) {
110: sb.insert(0, ID_SEP);
111: if (currentBeanInstance instanceof UIForm) {
112: formEncountered = true;
113: break;
114: } else {
115: String currentCompId = currentBean
116: .getInstanceName();
117: if (currentCompId == null) {
118: return null;
119: }
120: sb.insert(0, currentCompId);
121: }
122: }
123: currentBean = currentBean.getBeanParent();
124: }
125: if (formEncountered) {
126: return sb.toString();
127: } else {
128: return null;
129: }
130: }
131:
132: /**
133: * <p>Designtime version of
134: * <code>Form.isValidFullyQualifiedId(String)</code> for jsfcl.
135: */
136: /*
137: * Be sure to keep this method in sync with the version in
138: * <code>com.sun.rave.web.ui.component.Form</code> (in webui).</p>
139: */
140: public static boolean isValidFullyQualifiedId(String id) {
141: return id != null && id.startsWith(ID_SEP)
142: && (id.length() == 1 || !id.endsWith(ID_SEP))
143: && !id.endsWith(ID_WILD) && id.indexOf(' ') == -1;
144: }
145:
146: /**
147: * <p>Designtime version of
148: * <code>Form.fullyQualifiedIdMatchesPattern(String, String)</code>
149: * for jsfcl.
150: */
151: /*
152: * Be sure to keep this method in sync with the version in
153: * <code>com.sun.rave.web.ui.component.Form</code> (in webui).</p>
154: */
155: public static boolean fullyQualifiedIdMatchesPattern(String fqId,
156: String pattern) {
157: if (!isValidFullyQualifiedId(fqId)) {
158: return false;
159: }
160: if (pattern == null || pattern.length() < 1
161: || pattern.indexOf(' ') != -1) {
162: return false;
163: }
164: //unless pattern is ":", it should not end with ":"
165: if (pattern.endsWith(ID_SEP) && !pattern.equals(ID_SEP)) {
166: return false;
167: }
168:
169: String wildSuffix = ID_SEP + ID_WILD;
170:
171: //if ID_WILD appears in pattern, it must be the last character, and preceded by ID_SEP
172: int indexOfWildInPattern = pattern.indexOf(ID_WILD);
173: if (indexOfWildInPattern != -1) {
174: if (indexOfWildInPattern != pattern.length() - 1) {
175: return false;
176: }
177: if (!pattern.endsWith(wildSuffix)) {
178: return false;
179: }
180: }
181:
182: if (pattern.equals(wildSuffix)) {
183: //if pattern was ":*", then any valid fqId is a match
184: return true;
185: } else if (pattern.endsWith(wildSuffix)) {
186: String patternPrefix = pattern.substring(0, pattern
187: .length()
188: - wildSuffix.length());
189: if (patternPrefix.startsWith(ID_SEP)) {
190: return fqId.equals(patternPrefix)
191: || fqId.startsWith(patternPrefix + ID_SEP);
192: } else {
193: return fqId.endsWith(ID_SEP + patternPrefix)
194: || fqId
195: .indexOf(ID_SEP + patternPrefix
196: + ID_SEP) > -1;
197: }
198: } else {
199: if (pattern.startsWith(ID_SEP)) {
200: return fqId.equals(pattern);
201: } else {
202: return fqId.endsWith(ID_SEP + pattern);
203: }
204: }
205: }
206:
207: /**
208: * <p>Designtime version of
209: * <code>Form.generateVirtualForms(String)</code>
210: * for jsfcl.
211: */
212: /*
213: * Be sure to keep this method in sync with the version in
214: * <code>com.sun.rave.web.ui.component.Form</code> (in webui).</p>
215: */
216: public static VirtualFormDescriptor[] generateVirtualForms(
217: String configStr) {
218: //formname1|pid1 pid2 pid3|sid1 sid2 sid3, formname2|pid4 pid5 pid6|sid4 sid5 sid6
219: if (configStr == null) {
220: return null;
221: }
222: configStr = configStr.trim();
223: if (configStr.length() < 1) {
224: return new VirtualFormDescriptor[0];
225: }
226: //configStr now can't be null, blank, or just ws
227:
228: StringTokenizer st = new StringTokenizer(configStr, VF_DELIM_1);
229: List vfs = new ArrayList(); //list of marshalled vfs
230: while (st.hasMoreTokens()) {
231: String vf = st.nextToken(); //not null, but could be just whitespace or blank
232: vf = vf.trim();
233: //vf could be a blank string
234: if (vf.length() > 0) {
235: vfs.add(vf);
236: }
237: }
238:
239: List descriptors = new ArrayList(); //a list of VirtualFormDescriptors
240: for (int i = 0; i < vfs.size(); i++) { //go through each marshalled vf
241: String vf = (String) vfs.get(i); //get the marshalled vf. not mere ws, blank, or null.
242: st = new StringTokenizer(vf, VF_DELIM_2);
243: String[] parts = new String[3]; //part1 is vf name, part2 is participating ids, part3 is submitting ids
244: int partIndex = 0;
245: while (partIndex < parts.length && st.hasMoreTokens()) {
246: String part = st.nextToken(); //not null, but could be whitespace or blank
247: part = part.trim(); //now can't be whitespace, but could be blank
248: if (part.length() > 0) {
249: //part is not null, whitespace, or blank
250: parts[partIndex] = part;
251: }
252: partIndex++;
253: }
254:
255: VirtualFormDescriptor vfd;
256: if (parts[0] != null) {
257: vfd = new VirtualFormDescriptor();
258: vfd.setName(parts[0]); //won't be null, blank, or just ws
259: descriptors.add(vfd);
260: } else {
261: continue; //this marshalled vf has no name. can't create a descriptor for it. go to next marshalled vf
262: }
263:
264: if (parts[1] != null) {
265: String pidString = parts[1]; //not null, blank, or just ws
266: st = new StringTokenizer(pidString);
267: List pidList = new ArrayList();
268: while (st.hasMoreTokens()) {
269: String pid = st.nextToken();
270: pidList.add(pid.trim());
271: }
272: String[] pids = (String[]) pidList
273: .toArray(new String[pidList.size()]); //size guaranteed to be at least 1
274: vfd.setParticipatingIds(pids);
275: }
276:
277: if (parts[2] != null) {
278: String sidString = parts[2]; //not null, blank, or just ws
279: st = new StringTokenizer(sidString);
280: List sidList = new ArrayList();
281: while (st.hasMoreTokens()) {
282: String sid = st.nextToken();
283: sidList.add(sid.trim());
284: }
285: String[] sids = (String[]) sidList
286: .toArray(new String[sidList.size()]); //size guaranteed to be at least 1
287: vfd.setSubmittingIds(sids);
288: }
289: }
290: return (VirtualFormDescriptor[]) descriptors
291: .toArray(new VirtualFormDescriptor[descriptors.size()]); //might be of size 0, but won't be null
292: }
293:
294: /**
295: * <p>Designtime version of
296: * <code>Form.generateVirtualFormsConfig(VirtualFormDescriptor[])</code>
297: * for jsfcl.
298: */
299: /*
300: * Be sure to keep this method in sync with the version in
301: * <code>com.sun.rave.web.ui.component.Form</code> (in webui).</p>
302: */
303: public static String generateVirtualFormsConfig(
304: VirtualFormDescriptor[] descriptors) {
305: if (descriptors == null) {
306: return null;
307: }
308: StringBuffer sb = new StringBuffer();
309: for (int i = 0; i < descriptors.length; i++) {
310: if (descriptors[i] != null) {
311: String vf = descriptors[i].toString();
312: if (vf.length() > 0) {
313: if (sb.length() > 0) {
314: sb.append(" , ");
315: }
316: sb.append(vf);
317: }
318: }
319: }
320: return sb.toString();
321: }
322:
323: /**
324: * <p>Designtime version of
325: * <code>Form.VirtualFormDescriptor</code>
326: * for jsfcl.
327: */
328: /*
329: * Be sure to keep this class in sync with the version in
330: * <code>com.sun.rave.web.ui.component.Form</code> (in webui).</p>
331: */
332: public static class VirtualFormDescriptor implements Serializable {
333: private String name; //name of the virtual form
334: private String[] participatingIds; //ids of components that participate
335: private String[] submittingIds; //ids of components that submit
336:
337: public VirtualFormDescriptor() {
338: }
339:
340: public VirtualFormDescriptor(String name) {
341: setName(name);
342: }
343:
344: public String getName() {
345: return name;
346: }
347:
348: public void setName(String name) {
349: if (name == null) {
350: throw new IllegalArgumentException(
351: "virtual form name was null"); //NOI18N
352: }
353: name = name.trim();
354: if (name.length() < 1) {
355: throw new IllegalArgumentException(
356: "virtual form name contained whitespace only"); //NOI18N
357: }
358: this .name = name;
359: }
360:
361: public String[] getParticipatingIds() {
362: return participatingIds;
363: }
364:
365: public void setParticipatingIds(
366: java.lang.String[] participatingIds) {
367: for (int i = 0; participatingIds != null
368: && i < participatingIds.length; i++) {
369: if (participatingIds[i] == null) {
370: throw new IllegalArgumentException(
371: "participating id at index " + i
372: + " was null"); //NOI18N
373: }
374: participatingIds[i] = participatingIds[i].trim();
375: if (participatingIds[i].length() < 1) {
376: throw new IllegalArgumentException(
377: "participating id at index " + i
378: + " contained whitespace only"); //NOI18N
379: }
380: }
381: this .participatingIds = participatingIds;
382: }
383:
384: public String[] getSubmittingIds() {
385: return submittingIds;
386: }
387:
388: public void setSubmittingIds(java.lang.String[] submittingIds) {
389: for (int i = 0; submittingIds != null
390: && i < submittingIds.length; i++) {
391: if (submittingIds[i] == null) {
392: throw new IllegalArgumentException(
393: "submitting id at index " + i + " was null"); //NOI18N
394: }
395: submittingIds[i] = submittingIds[i].trim();
396: if (submittingIds[i].length() < 1) {
397: throw new IllegalArgumentException(
398: "submitting id at index " + i
399: + " contained whitespace only"); //NOI18N
400: }
401: }
402: this .submittingIds = submittingIds;
403: }
404:
405: //return true if the component id provided submits this virtual form
406: public boolean isSubmittedBy(String fqId) {
407: if (!isValidFullyQualifiedId(fqId))
408: return false;
409: for (int i = 0; submittingIds != null
410: && i < submittingIds.length; i++) {
411: if (fullyQualifiedIdMatchesPattern(fqId,
412: submittingIds[i])) {
413: return true;
414: }
415: }
416: return false;
417: }
418:
419: //return true if the component id provided participates in this virtual form
420: public boolean hasParticipant(String fqId) {
421: if (!isValidFullyQualifiedId(fqId))
422: return false;
423: for (int i = 0; participatingIds != null
424: && i < participatingIds.length; i++) {
425: if (fullyQualifiedIdMatchesPattern(fqId,
426: participatingIds[i])) {
427: return true;
428: }
429: }
430: return false;
431: }
432:
433: public String toString() {
434: if (name == null) {
435: return "";
436: } //NOI18N
437: StringBuffer sb = new StringBuffer();
438: sb.append(name);
439: sb.append(" | "); //NOI18N
440: for (int i = 0; participatingIds != null
441: && i < participatingIds.length; i++) {
442: sb.append(participatingIds[i]);
443: sb.append(' ');
444: }
445: sb.append("| "); //NOI18N
446: for (int i = 0; submittingIds != null
447: && i < submittingIds.length; i++) {
448: sb.append(submittingIds[i]);
449: sb.append(' ');
450: }
451: return sb.toString().trim();
452: }
453: }
454: }
|