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:
042: package org.netbeans.modules.form;
043:
044: import java.util.ArrayList;
045: import java.util.List;
046:
047: /**
048: * This class holds code-related data of one component in a representation
049: * suitable for editing in the customizer dialog.
050: *
051: * @author Tomas Pavek
052: */
053:
054: class CustomCodeData {
055:
056: enum CodeCategory {
057: CREATE_AND_INIT, DECLARATION
058: }
059:
060: private CodeCategory defaultCategory = CodeCategory.CREATE_AND_INIT;
061:
062: // creation and initialization code
063: private List<EditableBlock> initEditableBlocks = new ArrayList<EditableBlock>();
064: private List<GuardedBlock> initGuardedBlocks = new ArrayList<GuardedBlock>();
065:
066: // declaration code
067: private VariableDeclaration declaration;
068: private List<EditableBlock> declarationEditableBlocks = new ArrayList<EditableBlock>();
069: private List<GuardedBlock> declarationGuardedBlocks = new ArrayList<GuardedBlock>();
070:
071: private int highestPreference; // used temporarily when filling in editable blocks
072:
073: CustomCodeData() {
074: }
075:
076: int getEditableBlockCount(CodeCategory category) {
077: return getEditableList(category).size();
078: }
079:
080: EditableBlock getEditableBlock(CodeCategory category, int index) {
081: return getEditableList(category).get(index);
082: }
083:
084: int getGuardedBlockCount(CodeCategory category) {
085: return getGuardedList(category).size();
086: }
087:
088: GuardedBlock getGuardedBlock(CodeCategory category, int index) {
089: return getGuardedList(category).get(index);
090: }
091:
092: VariableDeclaration getDeclarationData() {
093: return declaration;
094: }
095:
096: // -----
097:
098: void addEditableBlock(String code, FormProperty targetProperty,
099: int preferenceIndex, // String propName
100: String displayName, String hint) {
101: addEditableBlock(null, code, targetProperty, preferenceIndex,
102: displayName, hint, false, false);
103: }
104:
105: void addEditableBlock(String code, FormProperty targetProperty,
106: int preferenceIndex, // String propName
107: String displayName, String hint, boolean pre, boolean post) {
108: addEditableBlock(null, code, targetProperty, preferenceIndex,
109: displayName, hint, pre, post);
110: }
111:
112: void addEditableBlock(CodeCategory category, String code,
113: FormProperty targetProperty, int preferenceIndex, // String propName
114: String displayName, String hint, boolean pre, boolean post) {
115: if (category == null)
116: category = defaultCategory;
117:
118: List<EditableBlock> editList = getEditableList(category);
119: if (editList.size() <= getGuardedList(category).size()) {
120: highestPreference = 0;
121: editList.add(new EditableBlock());
122: }
123: EditableBlock eBlock = editList.get(editList.size() - 1);
124: eBlock.addEntry(new CodeEntry(code, targetProperty,
125: displayName, hint, pre, post),
126: preferenceIndex > highestPreference);
127: if (preferenceIndex > highestPreference)
128: highestPreference = preferenceIndex;
129: }
130:
131: void addGuardedBlock(String code) {
132: addGuardedBlock(null, code, null, null, false, null, null, null);
133: }
134:
135: void addGuardedBlock(String defaultCode, String customCode,
136: String customCodeMark, boolean customized,
137: FormProperty targetProperty, String displayName, String hint) // String propName
138: {
139: addGuardedBlock(null, defaultCode, customCode, customCodeMark,
140: customized, targetProperty, displayName, hint);
141: }
142:
143: void addGuardedBlock(CodeCategory category, String defaultCode,
144: String customCode, String customCodeMark,
145: boolean customized, FormProperty targetProperty,
146: String displayName, String hint) // String propName
147: {
148: if (category == null)
149: category = defaultCategory;
150:
151: assert getGuardedList(category).size() + 1 == getEditableList(
152: category).size();
153:
154: CodeEntry customEntry = null;
155: int guardHeading = 0;
156: int guardEnding = 0;
157: if (customCode != null) {
158: int codeLen = customCode.length();
159: int first = customCode.indexOf(customCodeMark);
160: int last = customCode.lastIndexOf(customCodeMark);
161: if (first > 0 && last < codeLen - 1) { // not a first or last char
162: int markLen = customCodeMark.length();
163: String customizablePart = customCode.substring(first
164: + markLen, last);
165: customCode = customCode.substring(0, first)
166: + customizablePart
167: + customCode.substring(last + markLen);
168: guardHeading = first;
169: guardEnding = codeLen - markLen - last;
170: customEntry = new CodeEntry(
171: customized ? customizablePart : null,
172: targetProperty, displayName, hint, false, false);
173: } else
174: customCode = null; // no customizable section
175: }
176:
177: GuardedBlock gBlock = new GuardedBlock(defaultCode, customCode,
178: guardHeading, guardEnding, customized, customEntry);
179: getGuardedList(category).add(gBlock);
180: }
181:
182: void setDefaultCategory(CodeCategory category) {
183: defaultCategory = category;
184: }
185:
186: void setDeclarationData(boolean local, int modifiers) {
187: declaration = new VariableDeclaration(local, modifiers);
188: }
189:
190: // -----
191:
192: private List<EditableBlock> getEditableList(CodeCategory category) {
193: switch (category) {
194: case CREATE_AND_INIT:
195: return initEditableBlocks;
196: case DECLARATION:
197: return declarationEditableBlocks;
198: }
199: return null;
200: }
201:
202: private List<GuardedBlock> getGuardedList(CodeCategory category) {
203: switch (category) {
204: case CREATE_AND_INIT:
205: return initGuardedBlocks;
206: case DECLARATION:
207: return declarationGuardedBlocks;
208: }
209: return null;
210: }
211:
212: // -----
213:
214: void check() {
215: checkEditableGuardedPairs(initEditableBlocks, initGuardedBlocks);
216: checkEditableGuardedPairs(declarationEditableBlocks,
217: declarationGuardedBlocks);
218: }
219:
220: private void checkEditableGuardedPairs(List<EditableBlock> eList,
221: List<GuardedBlock> gList) {
222: assert (eList.size() == 0 && gList.size() == 0)
223: || eList.size() == gList.size() + 1;
224: }
225:
226: // -----
227:
228: /** Holds custom code and its origin (property where it is stored).*/
229: static class CodeEntry {
230: private String code;
231:
232: private FormProperty targetProperty;
233: private String displayName;
234: private String hint;
235: private boolean pre; // whether stored as pre-code of the property
236: private boolean post; // whether stored as post-code of the property
237:
238: private CodeEntry(String code,
239: FormProperty prop, // String name
240: String displayName, String hint, boolean pre,
241: boolean post) {
242: assert (!pre && !post) || pre != post;
243: this .code = code;
244: this .targetProperty = prop;
245: this .displayName = displayName;
246: this .hint = hint;
247: this .pre = pre;
248: this .post = post;
249: }
250:
251: String getCode() {
252: return code;
253: }
254:
255: void setCode(String code) {
256: this .code = code;
257: }
258:
259: String getName() {
260: return targetProperty.getName();
261: }
262:
263: String getDisplayName() {
264: return displayName;
265: }
266:
267: String getToolTipText() {
268: return hint;
269: }
270:
271: FormProperty getTargetProperty() {
272: return targetProperty;
273: }
274:
275: boolean isPropertyPreInit() {
276: return pre;
277: }
278:
279: boolean isPropertyPostInit() {
280: return post;
281: }
282:
283: @Override
284: public String toString() {
285: return displayName;
286: }
287: }
288:
289: static class EditableBlock {
290: private List<CodeEntry> entries = new ArrayList<CodeEntry>();
291: private int prefEntryIndex;
292:
293: private void addEntry(CodeEntry e, boolean preferred) {
294: entries.add(e);
295: if (preferred)
296: prefEntryIndex = entries.size() - 1;
297: }
298:
299: int getPreferredEntryIndex() {
300: return prefEntryIndex;
301: }
302:
303: CodeEntry[] getEntries() {
304: return entries.toArray(new CodeEntry[entries.size()]);
305: }
306: }
307:
308: static class GuardedBlock {
309: private String defaultCode;
310: private String customCode;
311: private int headerLength; // number of guarded chars before customizable area
312: private int footerLength; // number of guarded chars following the customizable area
313: private boolean customCodeSet;
314: private CodeEntry customEntry; // describes where the custom code is stored
315:
316: private GuardedBlock(String defaultCode, String customCode,
317: int header, int footer, boolean customSet,
318: CodeEntry customEntry) {
319: this .defaultCode = defaultCode;
320: this .customCode = customCode;
321: this .headerLength = header;
322: this .footerLength = footer;
323: this .customCodeSet = customSet;
324: this .customEntry = customEntry;
325: }
326:
327: String getDefaultCode() {
328: return defaultCode;
329: }
330:
331: String getCustomCode() {
332: return customCode;
333: }
334:
335: void setCustomizedCode(String code) {
336: customEntry.setCode(code);
337: if (code != null) {
338: customCode = customCode.substring(0, headerLength)
339: + code
340: + customCode.substring(customCode.length()
341: - footerLength);
342: customCodeSet = true;
343: } else {
344: customCodeSet = false;
345: }
346: }
347:
348: boolean isCustomizable() {
349: return customCode != null;
350: }
351:
352: boolean isCustomized() {
353: return customCodeSet;
354: }
355:
356: CodeEntry getCustomEntry() {
357: return customEntry;
358: }
359:
360: int getHeaderLength() {
361: return headerLength;
362: }
363:
364: int getFooterLength() {
365: return footerLength;
366: }
367: }
368:
369: static class VariableDeclaration {
370: boolean local;
371: int modifiers; // combination of java.lang.reflect.Modifier constants
372:
373: private VariableDeclaration(boolean local, int modifiers) {
374: this.local = local;
375: this.modifiers = modifiers;
376: }
377: }
378: }
|