KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > properties > PropertiesStructure


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.modules.properties;
22
23
24 import java.io.*;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import javax.swing.text.BadLocationException JavaDoc;
29
30 import org.openide.text.PositionBounds;
31 import org.openide.ErrorManager;
32
33
34 /**
35  * Element structure for one .properties file tightly
36  * bound with that file's document.
37  *
38  * @author Petr Jiricka
39  */

40 public class PropertiesStructure extends Element {
41
42     /**
43      * Map&lt;<code>String</code> to <code>Element.ItemElem</code>&gt;.
44      */

45     private Map JavaDoc<String JavaDoc,Element.ItemElem> items;
46
47     /** If active, contains link to its handler (parent) */
48     private StructHandler handler;
49
50     /** Generated serial version UID. */
51     static final long serialVersionUID = -78380271920882131L;
52     
53     
54     /** Constructs a new PropertiesStructure for the given bounds and items. */
55     public PropertiesStructure(PositionBounds bounds, Map JavaDoc<String JavaDoc,Element.ItemElem> items) {
56         super(bounds);
57         // set this structure as a parent for all elements
58
for (Element.ItemElem itemElem : items.values()) {
59             itemElem.setParent(this);
60         }
61         this.items = items;
62     }
63
64     
65     /** Updates the current structure by the new structure obtained by reparsing the document.
66      * Looks for changes between the structures and according to them calls update methods.
67      */

68     public void update(PropertiesStructure struct) {
69         synchronized(getParent()) {
70         synchronized(getParentBundleStructure()) {
71             boolean structChanged = false;
72             Element.ItemElem oldItem;
73
74             Map JavaDoc<String JavaDoc,Element.ItemElem> new_items = struct.items;
75             Map JavaDoc<String JavaDoc,Element.ItemElem> changed = new HashMap JavaDoc<String JavaDoc,Element.ItemElem>();
76             Map JavaDoc<String JavaDoc,Element.ItemElem> inserted = new HashMap JavaDoc<String JavaDoc,Element.ItemElem>();
77             Map JavaDoc<String JavaDoc,Element.ItemElem> deleted = new HashMap JavaDoc<String JavaDoc,Element.ItemElem>();
78
79             for (Element.ItemElem curItem : new_items.values()) {
80                 curItem.setParent(this);
81                 oldItem = getItem(curItem.getKey());
82                 if (oldItem == null) {
83                     inserted.put(curItem.getKey(), curItem);
84                 } else {
85                     if (!curItem.equals(oldItem)) {
86                         changed.put(curItem.getKey(), curItem);
87                     }
88                     items.remove(oldItem.getKey());
89                 }
90             }
91
92             deleted = items;
93             if ((deleted.size() > 0) || (inserted.size() > 0)) {
94                 structChanged = true;
95             }
96             // assign the new structure
97
items = new_items;
98
99             // Update bounds.
100
this.bounds = struct.getBounds();
101             
102             // notification
103
if (structChanged) {
104                 structureChanged(changed, inserted, deleted);
105             } else {
106                 // notify about changes in all items
107
for (Element.ItemElem itemElem : changed.values()) {
108                     itemChanged(itemElem);
109                 }
110             }
111         }
112         }
113     }
114
115     /** Sets the parent of this element. */
116     void setParent(StructHandler parent) {
117         handler = parent;
118     }
119
120     /** Gets parent for this properties structure.
121      * @return <code>StructureHandler</code> instance. */

122     public StructHandler getParent() {
123         if (handler == null) {
124             throw new IllegalStateException JavaDoc();
125         }
126         return handler;
127     }
128
129     /** Gets bundle structure of bundles where this .properties file belongs to. */
130     private BundleStructure getParentBundleStructure() {
131         PropertiesDataObject dataObj;
132         dataObj = (PropertiesDataObject) getParent().getEntry().getDataObject();
133         return dataObj.getBundleStructure();
134     }
135
136     /** Prints all structure to document.
137      * @return the structure dump */

138     public String JavaDoc getDocumentString() {
139         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
140         for (Element.ItemElem item : items.values()) {
141             sb.append(item.getDocumentString());
142         }
143         
144         return sb.toString();
145     }
146
147     /** Overrides superclass method.
148      * @return the formatted structure dump */

149     public String JavaDoc toString() {
150         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
151         for (Element.ItemElem item : items.values()) {
152             sb.append(item.toString());
153             sb.append("- - -\n"); //NOI18N
154
}
155         
156         return sb.toString();
157     }
158
159     /**
160      * Retrieves an item by key (property name) or null if does not exist.
161      * @param key Java string (unescaped)
162      */

163     public Element.ItemElem getItem(String JavaDoc key) {
164         return items.get(key);
165     }
166
167     /**
168      * Renames an item.
169      * @param oldKey nonescaped original name
170      * @param newKey nonescaped new name
171      * @return true if the item has been renamed successfully, false if another item with the same name exists.
172      */

173     public boolean renameItem(String JavaDoc oldKey, String JavaDoc newKey) {
174         synchronized(getParent()) {
175         synchronized(getParentBundleStructure()) {
176             Element.ItemElem item = getItem(newKey);
177             if (item == null) {
178                 item = getItem(oldKey);
179                 if (item == null) {
180                     return false;
181                 }
182                 items.remove(oldKey);
183                 items.put(newKey, item);
184                 item.setKey(newKey); // fires itemKeyChanged()
185
return true;
186             }
187             else {
188                 return false;
189             }
190         }
191         }
192     }
193
194     /** Deletes an item from the structure, if exists.
195      * @return <code>true<code> if the item has been deleted successfully, <code>false</code> otherwise */

196     public boolean deleteItem(String JavaDoc key) {
197         synchronized(getParent()) {
198         synchronized(getParentBundleStructure()) {
199             Element.ItemElem item = getItem(key);
200             
201             if (item == null) {
202                 return false;
203             }
204             try {
205                 item.getBounds().setText(""); // NOI18N
206
items.remove(key);
207                 structureChanged(); //??? fired from under lock
208
return true;
209             } catch (IOException e) {
210                 ErrorManager.getDefault().notify(e);
211                 return false;
212             } catch (BadLocationException JavaDoc e) {
213                 ErrorManager.getDefault().notify(e);
214                 return false;
215             }
216         }
217         }
218     }
219
220     /**
221      * Adds an item to the end of the file, or before the terminating comment,
222      * if there is any.
223      *
224      * @return <code>true</code> if the item has been added successfully, <code>false</code> otherwise
225      */

226     public boolean addItem(String JavaDoc key, String JavaDoc value, String JavaDoc comment) {
227         Element.ItemElem item = getItem(key);
228         if (item != null) {
229             return false;
230         }
231         // construct the new element
232
item = new Element.ItemElem(null,
233                                     new Element.KeyElem (null, key),
234                                     new Element.ValueElem (null, value),
235                                     new Element.CommentElem(null, comment));
236         // find the position where to add it
237
try {
238             synchronized(getParent()) {
239             synchronized(getParentBundleStructure()) {
240                 PositionBounds pos = getBounds();
241                 
242                 PositionBounds itemBounds
243                         = pos.insertAfter("\n")
244                              .insertAfter(item.getDocumentString());
245                 item.bounds = itemBounds;
246
247                 //#17044 update in-memory model
248
item.setParent(this);
249                 items.put(key, item);
250                 structureChanged();
251                 
252                 return true;
253             }
254             }
255         } catch (IOException ioe) {
256             return false;
257         } catch (BadLocationException JavaDoc ble) {
258             return false;
259         }
260     }
261
262     /** Returns iterator thropugh all items, including empty ones */
263     public Iterator JavaDoc<Element.ItemElem> allItems() {
264         return items.values().iterator();
265     }
266
267     /** Notification that the given item has changed (its value or comment) */
268     void itemChanged(Element.ItemElem elem) {
269         getParentBundleStructure().notifyItemChanged(this, elem);
270     }
271
272     /** Notification that the structure has changed (no specific information). */
273     void structureChanged() {
274         getParentBundleStructure().notifyOneFileChanged(getParent());
275     }
276
277     /** Notification that the structure has changed (items have been added or
278      * deleted, also includes changing an item's key). */

279     void structureChanged(Map JavaDoc<String JavaDoc,Element.ItemElem> changed,
280                           Map JavaDoc<String JavaDoc,Element.ItemElem> inserted,
281                           Map JavaDoc<String JavaDoc,Element.ItemElem> deleted) {
282         getParentBundleStructure().notifyOneFileChanged(
283                 getParent(),
284                 changed,
285                 inserted,
286                 deleted);
287     }
288
289     /**
290      * Notification that an item's key has changed. Subcase of structureChanged().
291      * Think twice when using this - don't I need to reparse all files ?
292      */

293     void itemKeyChanged(String JavaDoc oldKey, Element.ItemElem newElem) {
294         // structural change information - watch: there may be two properties of the same name !
295
// maybe this is unnecessary
296
Map JavaDoc<String JavaDoc,Element.ItemElem> changed = new HashMap JavaDoc<String JavaDoc,Element.ItemElem>();
297         Map JavaDoc<String JavaDoc,Element.ItemElem> inserted = new HashMap JavaDoc<String JavaDoc,Element.ItemElem>();
298         Map JavaDoc<String JavaDoc,Element.ItemElem> deleted = new HashMap JavaDoc<String JavaDoc,Element.ItemElem>();
299
300         // old key
301
Element.ItemElem item = getItem(oldKey);
302         if (item == null) {
303             // old key deleted
304
Element.ItemElem emptyItem = new Element.ItemElem(
305                     null,
306                     new Element.KeyElem(null, oldKey),
307                     new Element.ValueElem(null, ""), //NOI18N
308
new Element.CommentElem(null, "")); //NOI18N
309
deleted.put(oldKey, emptyItem);
310         } else {
311             // old key changed
312
changed.put(item.getKey(), item);
313         }
314         // new key
315
inserted.put(newElem.getKey(), newElem);
316
317         structureChanged(changed, inserted, deleted);
318     }
319 }
320
Popular Tags