001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2008 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: package org.netbeans.modules.cnd.highlight.semantic;
042:
043: import java.awt.Color;
044: import java.lang.ref.Reference;
045: import java.lang.ref.WeakReference;
046: import java.util.ArrayList;
047: import java.util.Collection;
048: import java.util.Collections;
049: import java.util.LinkedList;
050: import java.util.List;
051: import java.util.Map;
052: import java.util.WeakHashMap;
053: import javax.swing.text.BadLocationException;
054: import javax.swing.text.Document;
055: import javax.swing.text.Position;
056: import javax.swing.text.StyledDocument;
057: import org.netbeans.modules.cnd.api.model.xref.CsmReference;
058: import org.netbeans.modules.editor.errorstripe.privatespi.Mark;
059: import org.netbeans.modules.editor.errorstripe.privatespi.MarkProvider;
060: import org.netbeans.modules.editor.errorstripe.privatespi.Status;
061: import org.openide.text.NbDocument;
062: import org.openide.util.Exceptions;
063:
064: public class OccurrencesMarkProvider extends MarkProvider {
065:
066: private static Map<Document, Reference<OccurrencesMarkProvider>> providers = new WeakHashMap<Document, Reference<OccurrencesMarkProvider>>();
067:
068: public static synchronized OccurrencesMarkProvider get(Document doc) {
069: Reference<OccurrencesMarkProvider> ref = providers.get(doc);
070: OccurrencesMarkProvider p = ref != null ? ref.get() : null;
071:
072: if (p == null) {
073: providers.put(doc,
074: new WeakReference<OccurrencesMarkProvider>(
075: p = new OccurrencesMarkProvider()));
076: }
077:
078: return p;
079: }
080:
081: private List<Mark> semantic;
082: private List<Mark> occurrences;
083: private List<Mark> joint;
084:
085: /** Creates a new instance of OccurrencesMarkProvider */
086: private OccurrencesMarkProvider() {
087: semantic = Collections.emptyList();
088: occurrences = Collections.emptyList();
089: joint = Collections.emptyList();
090: }
091:
092: public synchronized List<Mark> getMarks() {
093: return joint;
094: }
095:
096: public void setSematic(Collection<Mark> s) {
097: List<Mark> old;
098: List<Mark> nue;
099:
100: synchronized (this ) {
101: semantic = new ArrayList<Mark>(s);
102:
103: old = joint;
104:
105: nue = joint = new ArrayList<Mark>();
106:
107: joint.addAll(semantic);
108: joint.addAll(occurrences);
109: }
110:
111: firePropertyChange(PROP_MARKS, old, nue);
112: }
113:
114: public void setOccurrences(Collection<Mark> s) {
115: List<Mark> old;
116: List<Mark> nue;
117:
118: synchronized (this ) {
119: occurrences = new ArrayList<Mark>(s);
120:
121: old = joint;
122:
123: nue = joint = new ArrayList<Mark>();
124:
125: joint.addAll(semantic);
126: joint.addAll(occurrences);
127: }
128:
129: //#85919: fire outside the lock:
130: firePropertyChange(PROP_MARKS, old, nue);
131: }
132:
133: public static Collection<Mark> createMarks(final Document doc,
134: final Collection<CsmReference> list, final Color color,
135: final String tooltip) {
136: final List<Mark> result = new LinkedList<Mark>();
137:
138: doc.render(new Runnable() {
139: public void run() {
140: for (CsmReference ref : list) {
141: try {
142: if (ref.getStartOffset() < doc.getLength()) {
143: result.add(new MarkImpl(doc, doc
144: .createPosition(ref
145: .getStartOffset()), color,
146: tooltip));
147: }
148: } catch (BadLocationException ex) {
149: Exceptions.printStackTrace(ex);
150: }
151: }
152: }
153: });
154:
155: return result;
156: }
157:
158: private static final class MarkImpl implements Mark {
159:
160: private Document doc;
161: private Position startOffset;
162: private Color color;
163: private String tooltip;
164:
165: public MarkImpl(Document doc, Position startOffset,
166: Color color, String tooltip) {
167: this .doc = doc;
168: this .startOffset = startOffset;
169: this .color = color;
170: this .tooltip = tooltip;
171: }
172:
173: public int getType() {
174: return TYPE_ERROR_LIKE;
175: }
176:
177: public Status getStatus() {
178: return Status.STATUS_OK;
179: }
180:
181: public int getPriority() {
182: return PRIORITY_DEFAULT;
183: }
184:
185: public Color getEnhancedColor() {
186: return color;
187: }
188:
189: public int[] getAssignedLines() {
190: int line = NbDocument.findLineNumber((StyledDocument) doc,
191: startOffset.getOffset());
192:
193: return new int[] { line, line };
194: }
195:
196: public String getShortDescription() {
197: return tooltip;
198: }
199:
200: }
201: }
|