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.propertyeditors;
042:
043: import com.sun.rave.designtime.Constants;
044: import com.sun.rave.designtime.DesignContext;
045: import com.sun.rave.designtime.DesignProperty;
046: import java.awt.Component;
047: import java.nio.CharBuffer;
048: import java.text.Collator;
049: import java.util.ArrayList;
050: import java.util.Arrays;
051: import java.util.List;
052: import java.util.Locale;
053:
054: /**
055: * An editor for properties that take CSS style classes. The editor will accept
056: * one or more of the style classes defined by all CSS style sheets in the
057: * current project. Inline editing of style classes is allowed, however, the
058: * style class names entered must correspond to style classes defined by style
059: * sheets in project scope.
060: *
061: * @author gjmurphy
062: */
063: public class StyleClassPropertyEditor extends PropertyEditorBase
064: implements
065: com.sun.rave.propertyeditors.StyleClassPropertyEditor {
066:
067: List styleClassList;
068:
069: String[] getStyleClasses() {
070: if (this .styleClassList == null)
071: return new String[0];
072: return (String[]) this .styleClassList
073: .toArray(new String[this .styleClassList.size()]);
074: }
075:
076: void setStyleClasses(String[] styleClasses) {
077: this .styleClassList = Arrays.asList(styleClasses);
078: }
079:
080: public Object getValue() {
081: if (styleClassList == null || styleClassList.size() == 0)
082: return null;
083: return getAsText();
084: }
085:
086: public void setValue(Object value) {
087: String text = (String) value;
088: if (text == null || text.trim().length() == 0) {
089: this .styleClassList = null;
090: } else {
091: this .styleClassList = Arrays.asList(text.trim()
092: .split("\\s"));
093: }
094: }
095:
096: public String getAsText() {
097: if (styleClassList == null || styleClassList.size() == 0)
098: return "";
099: StringBuffer buffer = new StringBuffer();
100: buffer.append(styleClassList.get(0));
101: for (int i = 1; i < styleClassList.size(); i++) {
102: buffer.append(" ");
103: buffer.append(styleClassList.get(i));
104: }
105: return buffer.toString();
106: }
107:
108: public void setAsText(String text) throws IllegalArgumentException {
109: text = text.trim();
110: if (text == null || text.length() == 0) {
111: this .styleClassList = null;
112: } else {
113: String[] styleClasses = null;
114: String styleClass = null;
115: if (text.contains(",")) {
116: // text is comma delimited.
117: int size = text.length();
118: CharBuffer charBuff = CharBuffer.allocate(size);
119: char c;
120: boolean commaFound = false;
121: for (int index = 0; index < size; index++) {
122: c = text.charAt(index);
123: if (c == ',') {
124: commaFound = true;
125: // Check if the previous charecters are space.
126: // If so, set the position to the first non-space
127: // charecter.
128: int pos = charBuff.position() - 1;
129: while (charBuff.get(pos) == ' ') {
130: pos--;
131: }
132: charBuff.position(++pos);
133:
134: }
135: if (commaFound && c != ',') {
136: if (c == ' ') {
137: // Don't add spaces that are
138: // followed the comma.
139: continue;
140: } else {
141: commaFound = false;
142: }
143: }
144: charBuff.append(c);
145: }
146: // rewind the buffer.
147: charBuff.rewind();
148: String newText = charBuff.toString();
149: styleClasses = newText.trim().split(" ");
150: this .styleClassList = new ArrayList();
151: for (int i = 0; i < styleClasses.length; i++) {
152: styleClass = styleClasses[i];
153: if (styleClass.length() != 0) {
154: this .styleClassList.add(styleClass);
155: }
156: }
157: } else {
158: // text is space separated.
159: styleClasses = text.split("\\s");
160: String[] styleClassesInContext = getAvailableStyleClasses();
161: this .styleClassList = new ArrayList();
162: List notFoundStyleClassList = new ArrayList();
163: for (int i = 0; i < styleClasses.length; i++) {
164: int index = Arrays.binarySearch(
165: styleClassesInContext, styleClasses[i]);
166: if (index >= 0)
167: this .styleClassList
168: .add(styleClassesInContext[index]);
169: else
170: notFoundStyleClassList.add(styleClasses[i]);
171: }
172: if (notFoundStyleClassList.size() > 0) {
173: throw new IllegalTextArgumentException(
174: bundle
175: .getMessage(
176: "StyleClassPropertyEditor.classNotFound",
177: notFoundStyleClassList
178: .toString()));
179: }
180: }
181: }
182: }
183:
184: public boolean supportsCustomEditor() {
185: return true;
186: }
187:
188: public Component getCustomEditor() {
189: return new StyleClassPropertyPanel(this );
190: }
191:
192: String[] getAvailableStyleClasses() {
193: DesignProperty designProperty = this .getDesignProperty();
194: if (designProperty == null)
195: return new String[0];
196: DesignContext designContext = designProperty.getDesignBean()
197: .getDesignContext();
198: // According to the API documentation, this should return an array of
199: // StyleClassDescriptor objects, but this does not appear to have been
200: // implemented yet.
201: Object[] styleClasses = (Object[]) designContext
202: .getContextData(Constants.ContextData.CSS_STYLE_CLASS_DESCRIPTORS);
203: String[] styleClassNames = new String[styleClasses.length];
204: for (int i = 0; i < styleClasses.length; i++)
205: styleClassNames[i] = styleClasses[i].toString();
206: Collator collator = Collator.getInstance(Locale.US);
207: collator.setStrength(Collator.PRIMARY);
208: Arrays.sort(styleClassNames, collator);
209: return styleClassNames;
210: }
211: }
|