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 2005-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:
042: package org.openidex.search;
043:
044: import java.beans.PropertyChangeListener;
045: import java.beans.PropertyChangeSupport;
046: import java.util.ArrayList;
047: import java.util.Collections;
048: import java.util.List;
049:
050: /**
051: * Shareable search history. Known implementations are explorer search
052: * dialog and editor find&replace dialog.
053: *
054: * Typical use case:
055: * Editor registers a listener to listen on lastSelected SearchPattern. If user
056: * opens explorer's search dialog and perform search, a search expression is added
057: * into SearchHistory and lastSelected SearchPattern is setted. The event is fired,
058: * editor can retrieve lastSelected SearchPattern and in accordance with its parameters
059: * it can highlight(in yellow) all matched patterns. If editor dialog is open,
060: * it contains shareable SearchHistory. Another direction is search in editor, that
061: * adds a SearchPattern in SearchHistory, thus the new item is available also in
062: * explorer's search dialog.
063: *
064: * @since org.openidex.util/3 3.5, NB 4.1
065: * @author Martin Roskanin
066: */
067: public final class SearchHistory {
068:
069: /** Last selected SearchPattern. */
070: private SearchPattern lastSelected;
071:
072: /** Support for listeners */
073: private PropertyChangeSupport pcs;
074:
075: /** Maximum items allowed in searchPatternsList */
076: private static final int MAX_SEARCH_PATTERNS_ITEMS = 50;
077:
078: /** Shareable SearchPattern history. It is a List of SearchPatterns */
079: private List<SearchPattern> searchPatternsList = new ArrayList<SearchPattern>(
080: MAX_SEARCH_PATTERNS_ITEMS);
081:
082: /** Singleton instance */
083: private static SearchHistory INSTANCE = null;
084:
085: /** Property name for last selected search pattern
086: * Firing:
087: * oldValue - old selected pattern
088: * newValue - new selected pattern
089: */
090: public final static String LAST_SELECTED = "last-selected"; //NOI18N
091:
092: /** Property name for adding pattern to history
093: * Firing:
094: * oldValue - null
095: * newValue - added pattern
096: */
097: public final static String ADD_TO_HISTORY = "add-to-history"; //NOI18N
098:
099: /** Creates a new instance of SearchHistory */
100: private SearchHistory() {
101: }
102:
103: /** @return singleton instance of SearchHistory */
104: public synchronized static SearchHistory getDefault() {
105: if (INSTANCE == null) {
106: INSTANCE = new SearchHistory();
107: }
108: return INSTANCE;
109: }
110:
111: /** @return last selected SearchPattern */
112: public SearchPattern getLastSelected() {
113: return lastSelected;
114: }
115:
116: /** Sets last selected SearchPattern
117: * @param pattern last selected pattern
118: */
119: public void setLastSelected(SearchPattern pattern) {
120: SearchPattern oldPattern = this .lastSelected;
121: this .lastSelected = pattern;
122: if (pcs != null) {
123: pcs.firePropertyChange(LAST_SELECTED, oldPattern, pattern);
124: }
125: }
126:
127: private synchronized PropertyChangeSupport getPropertyChangeSupport() {
128: if (pcs == null) {
129: pcs = new PropertyChangeSupport(this );
130: }
131: return pcs;
132: }
133:
134: /** Adds a property change listener.
135: * @param pcl the listener to add
136: */
137: public void addPropertyChangeListener(PropertyChangeListener pcl) {
138: getPropertyChangeSupport().addPropertyChangeListener(pcl);
139: }
140:
141: /** Removes a property change listener.
142: * @param pcl the listener to remove
143: */
144: public void removePropertyChangeListener(PropertyChangeListener pcl) {
145: if (pcs != null) {
146: pcs.removePropertyChangeListener(pcl);
147: }
148: }
149:
150: /** @return unmodifiable List of SearchPatterns */
151: public synchronized List<SearchPattern> getSearchPatterns() {
152: return Collections.unmodifiableList(searchPatternsList);
153: }
154:
155: /** Adds SearchPattern to SearchHistory
156: * @param pattern the SearchPattern to add
157: */
158: public synchronized void add(SearchPattern pattern) {
159: if (pattern == null || pattern.getSearchExpression() == null
160: || pattern.getSearchExpression().length() == 0) {
161: return;
162: }
163: if (searchPatternsList.size() > 0
164: && pattern.equals(searchPatternsList.get(0))) {
165: return;
166: }
167: if (searchPatternsList.size() == MAX_SEARCH_PATTERNS_ITEMS) {
168: searchPatternsList.remove(MAX_SEARCH_PATTERNS_ITEMS - 1);
169: }
170: searchPatternsList.add(0, pattern);
171: if (pcs != null) {
172: pcs.firePropertyChange(ADD_TO_HISTORY, null, pattern);
173: }
174: }
175:
176: }
|