001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019: package org.netbeans.modules.soa.ui.form.valid;
020:
021: import java.awt.Component;
022: import java.awt.Container;
023: import java.util.ArrayList;
024: import java.util.Collections;
025: import java.util.HashMap;
026: import java.util.List;
027: import org.netbeans.modules.soa.ui.SoaConstants;
028: import org.netbeans.modules.soa.ui.form.valid.ValidStateManager.ValidStateListener;
029: import org.netbeans.modules.soa.ui.form.valid.Validator.Reason;
030: import org.netbeans.modules.soa.ui.form.valid.Validator.Severity;
031:
032: /**
033: *
034: * @author nk160297
035: */
036: public class DefaultValidStateManager implements ValidStateManager {
037:
038: private static String NBSP = " "; // NOI18N
039: private static String HTML = "<html>"; // NOI18N
040:
041: private HashMap<Validator, List<Reason>> myProblems;
042: private List<ValidStateListener> myListeners;
043: private List<Validator> validatorsToIgnor;
044:
045: public DefaultValidStateManager() {
046: myProblems = new HashMap<Validator, List<Reason>>();
047: myListeners = new ArrayList<ValidStateListener>();
048: validatorsToIgnor = new ArrayList<Validator>();
049: }
050:
051: public void clearReasons() {
052: boolean wasInvalid = !isValid();
053: myProblems.clear();
054: if (wasInvalid) {
055: fireStateChanged();
056: }
057: }
058:
059: public void processValidationResults(Validator validator) {
060: List<Reason> reasons = validator.getReasons();
061: if (isIgnorValidator(validator)) {
062: return;
063: }
064: if (!validator.hasReasons(null)) {
065: if (myProblems.containsKey(validator)) {
066: myProblems.remove(validator);
067: fireStateChanged();
068: }
069: } else {
070: boolean needUpdateReasons = false;
071: //
072: if (myProblems.containsKey(validator)) {
073: List<Reason> currReasons = myProblems.get(validator);
074: if (!equals(currReasons, reasons)) {
075: needUpdateReasons = true;
076: }
077: } else {
078: needUpdateReasons = true;
079: }
080: //
081: if (needUpdateReasons) {
082: // It's necessary to copy reasons' list here!!!
083: myProblems.put(validator,
084: new ArrayList<Reason>(reasons));
085: fireStateChanged();
086: }
087: }
088: }
089:
090: public void ignoreValidator(Validator validator, boolean flag) {
091: if (validator == null) {
092: return;
093: }
094: //
095: if (flag) {
096: // add validator to ignor
097: if (!validatorsToIgnor.contains(validator)) {
098: validatorsToIgnor.add(validator);
099: }
100: } else {
101: // remove validator to ignor
102: validatorsToIgnor.remove(validator);
103: }
104: }
105:
106: public boolean isIgnorValidator(Validator validator) {
107: return validatorsToIgnor.contains(validator);
108: }
109:
110: public void removeValidStateListener(ValidStateListener listener) {
111: myListeners.remove(listener);
112: }
113:
114: public void addValidStateListener(ValidStateListener listener) {
115: myListeners.add(listener);
116: }
117:
118: public boolean isValid() {
119: return myProblems.isEmpty();
120: }
121:
122: public Reason getFistReason(Severity severity) {
123: for (List<Reason> reasonsList : myProblems.values()) {
124: if (reasonsList != null && reasonsList.size() > 0) {
125: if (severity == null) {
126: return reasonsList.get(0);
127: } else {
128: for (Reason reason : reasonsList) {
129: if (reason.getSeverity() == severity) {
130: return reason;
131: }
132: }
133: }
134: }
135: }
136: return null;
137: }
138:
139: public List<Reason> getReasons(Severity severity) {
140: ArrayList<Reason> result = new ArrayList<Reason>();
141: for (List<Reason> reasonsList : myProblems.values()) {
142: if (reasonsList != null && reasonsList.size() > 0) {
143: if (severity == null) {
144: result.addAll(reasonsList);
145: } else {
146: for (Reason reason : reasonsList) {
147: if (reason.getSeverity() == severity) {
148: result.add(reason);
149: }
150: }
151: }
152: }
153: }
154: return result;
155: }
156:
157: /**
158: * Shows only first reason.
159: */
160: public String getHtmlReasons() {
161: StringBuffer sb = new StringBuffer();
162: //
163: // The following line is necessary to provide text wrapping in JLable controls
164: sb.append(HTML);
165: Reason firstReason = getFistReason(Severity.ERROR);
166: if (firstReason == null) {
167: firstReason = getFistReason(Severity.WARNING);
168: }
169: if (firstReason == null) {
170: String text = firstReason.getText();
171: if (text.startsWith(HTML)) {
172: // cut out the <html> tag from the reason text if it present
173: text = text.substring(HTML.length());
174: }
175: sb.append(text);
176: }
177: //
178: return sb.toString();
179: }
180:
181: // /**
182: // * Provides multiline text with full list of problems
183: // */
184: // public String getHtmlReasons() {
185: // StringBuffer sb = new StringBuffer();
186: // sb.append("<html>"); // NOI18N
187: // //
188: // String prefix = NbBundle.getMessage(
189: // DefaultValidStateManager.class, "ERR_COMMON_PREFIX"); // NOI18N
190: // sb.append(prefix).append("<p>"); // NOI18N
191: // //
192: // boolean firstLine = true;
193: // for (String reason : getReasons()) {
194: // if (firstLine) {
195: // firstLine = false;
196: // } else {
197: // sb.append("<br>"); // NOI18N
198: // }
199: // //
200: // sb.append(NBSP).append("-").append(NBSP).append(reason). // NOI18N
201: // append(" ").append(NBSP); // NOI18N
202: // }
203: // //
204: // return sb.toString();
205: // }
206:
207: private void fireStateChanged() {
208: boolean isValid = isValid();
209: for (ValidStateListener listener : myListeners) {
210: listener.stateChanged(this , isValid);
211: }
212: }
213:
214: private boolean equals(List<Reason> list1, List<Reason> list2) {
215: if (list1 == null && list2 == null) {
216: return true;
217: } else if (list1 == null && list2 != null) {
218: return false;
219: } else if (list1 != null && list2 == null) {
220: return false;
221: }
222: //
223: // Both lists is not null
224: if (list1.size() != list2.size()) {
225: return false;
226: } else {
227: //
228: // Both lists has the same size
229: for (int index = 0; index < list1.size(); index++) {
230: Reason rsn1 = list1.get(index);
231: Reason rsn2 = list2.get(index);
232: //
233: if (rsn1 != null) {
234: if (!rsn1.equals(rsn2)) {
235: return false;
236: }
237: } else if (rsn2 != null) {
238: if (!rsn2.equals(rsn1)) {
239: return false;
240: }
241: } else {
242: // Both str equals null --> continue
243: }
244: }
245: }
246: //
247: return true;
248: }
249:
250: public void validateChildrenControls(Container parent, boolean fast) {
251: validateChildrenControls(this , parent, fast);
252: }
253:
254: /**
255: * This method do recursive validation of the component's tree by
256: * looking validator providers.
257: */
258: public static void validateChildrenControls(ValidStateManager vsm,
259: Container parent, boolean fast) {
260: for (Component comp : parent.getComponents()) {
261: Validator validator = null;
262: if (comp instanceof Validator) {
263: validator = ((Validator) comp);
264: } else if (comp instanceof Validator.Provider) {
265: validator = ((Validator.Provider) comp).getValidator();
266: }
267: if (validator != null && !vsm.isIgnorValidator(validator)) {
268: validator.clearReasons();
269: validator.doValidation(fast);
270: vsm.processValidationResults(validator);
271: }
272: if (comp instanceof Container) {
273: validateChildrenControls(vsm, (Container) comp, fast);
274: }
275: }
276: }
277:
278: public static ValidStateManager findVSM(Component comp,
279: boolean isFast) {
280: while (comp != null) {
281: if (comp instanceof ValidStateManager.Provider) {
282: return ((ValidStateManager.Provider) comp)
283: .getValidStateManager(isFast);
284: } else {
285: comp = comp.getParent();
286: }
287: }
288: return null;
289: }
290:
291: public static class DefaultVsmProvider implements
292: ValidStateManager.Provider {
293:
294: private Component myComponent;
295:
296: public DefaultVsmProvider(Component comp) {
297: myComponent = comp;
298: }
299:
300: public ValidStateManager getValidStateManager(boolean isFast) {
301: return DefaultValidStateManager
302: .findVSM(myComponent, isFast);
303: }
304:
305: }
306:
307: }
|