--- a/properties/manifest.mf
+++ a/properties/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.modules.properties/1
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/properties/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.26
+OpenIDE-Module-Specification-Version: 1.27
OpenIDE-Module-Layer: org/netbeans/modules/properties/Layer.xml
AutoUpdate-Show-In-Client: false
--- a/properties/src/org/netbeans/modules/properties/BundleEditPanel.java
+++ a/properties/src/org/netbeans/modules/properties/BundleEditPanel.java
@@ -73,8 +73,11 @@
public class BundleEditPanel extends JPanel implements PropertyChangeListener {
/** PropertiesDataObject this panel presents. */
- private PropertiesDataObject obj;
-
+// private PropertiesDataObject obj;
+
+ /** */
+ private BundleStructure structure;
+
/** Document listener for value and comment textareas. */
private DocumentListener listener;
@@ -88,8 +91,10 @@
private int lastSelectedColumn;
/** Creates new form BundleEditPanel */
+ @Deprecated
public BundleEditPanel(final PropertiesDataObject obj, PropertiesTableModel propTableModel) {
- this.obj = obj;
+// this.obj = obj;
+ this.structure = obj.getBundleStructure();
initComponents();
initAccessibility();
@@ -153,7 +158,7 @@
obj.getBundleStructure().sort(modelIndex);
}
});
-
+
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
@@ -168,6 +173,89 @@
} // End of constructor.
+ /** Creates new form BundleEditPanel */
+ public BundleEditPanel(final BundleStructure structure, PropertiesTableModel propTableModel) {
+ this.structure = structure;
+
+ initComponents();
+ initAccessibility();
+ initSettings();
+
+ // Sets table column model.
+ table.setColumnModel(new TableViewColumnModel());
+
+ // Sets custom table header renderer (with sorting indicators).
+ JTableHeader header = table.getTableHeader();
+ header.setDefaultRenderer(
+ new TableViewHeaderRenderer(structure, header.getDefaultRenderer()));
+
+ // Sets table model.
+ table.setModel(propTableModel);
+
+ // Sets table cell editor.
+ JTextField textField = new JTextField();
+ // Force the document to accept newlines. The textField doesn't like
+ // it, but the same document is used by the textValue
text
+ // area that must accept newlines.
+ textField.getDocument().putProperty("filterNewlines", Boolean.FALSE); // NOI18N
+ textField.setBorder(new LineBorder(Color.black));
+ textField.getAccessibleContext().setAccessibleName(NbBundle.getBundle(BundleEditPanel.class).getString("ACSN_CellEditor"));
+ textField.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACSD_CellEditor"));
+ listener = new ModifiedListener();
+ table.setDefaultEditor(PropertiesTableModel.StringPair.class,
+ new PropertiesTableCellEditor(textField, textComment, textValue, valueLabel, listener));
+
+ // Sets renderer.
+ table.setDefaultRenderer(PropertiesTableModel.StringPair.class, new TableViewRenderer());
+
+ updateAddButton();
+
+ // property change listener - listens to editing state of the table
+ table.addPropertyChangeListener(new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("tableCellEditor")) { // NOI18N
+ updateEnabled();
+ } else if (evt.getPropertyName().equals("model")) { // NOI18N
+ updateAddButton();
+ }
+ }
+ });
+
+ // listens on clikcs on table header, detects column and sort accordingly to chosen one
+ table.getTableHeader().addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ TableColumnModel colModel = table.getColumnModel();
+ int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
+ // No column was clicked.
+ if (columnModelIndex < 0) {
+ return;
+ }
+ int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
+ // not detected column
+ if (modelIndex < 0) {
+ return;
+ }
+ structure.sort(modelIndex);
+ }
+ });
+
+ ListSelectionListener listSelectionListener = new ListSelectionListener() {
+
+ public void valueChanged(ListSelectionEvent evt) {
+ final boolean correctCellSelection = !selectionUpdateDisabled;
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ updateSelection(correctCellSelection);
+ }
+ });
+ }
+ };
+
+ table.getColumnModel().getSelectionModel().addListSelectionListener(listSelectionListener);
+ table.getSelectionModel().addListSelectionListener(listSelectionListener);
+
+ } // End of constructor.
/** Stops editing if editing is in run. */
protected void stopEditing() {
@@ -229,7 +317,7 @@
if (ex == null) {
return;
}
- String [] keys = obj.getBundleStructure().getKeys();
+ String [] keys = structure.getKeys();
int idx;
for (idx = 0; idx < keys.length; idx++) {
String key = keys[idx];
@@ -248,7 +336,7 @@
}
lastSelectedColumn = column;
- BundleStructure structure = obj.getBundleStructure();
+// BundleStructure structure = obj.getBundleStructure();
removeButton.setEnabled((row >= 0) && (!structure.isReadOnly()));
String value;
String comment;
@@ -281,14 +369,13 @@
}
private void updateAddButton() {
- addButton.setEnabled(!obj.getBundleStructure().isReadOnly());
+ addButton.setEnabled(!structure.isReadOnly());
}
/** Returns the main table with all values */
public JTable getTable() {
return table;
}
-
/** Initializes settings
variable. */
private void initSettings() {
@@ -511,10 +598,11 @@
if (DialogDisplayer.getDefault().notify(msg).equals(NotifyDescriptor.OK_OPTION)) {
try {
// Starts "atomic" acion for special undo redo manager of open support.
- obj.getOpenSupport().atomicUndoRedoFlag = new Object();
+// obj.getOpenSupport().atomicUndoRedoFlag = new Object();
+ structure.getOpenSupport().atomicUndoRedoFlag = new Object();
- for (int i=0; i < obj.getBundleStructure().getEntryCount(); i++) {
- PropertiesFileEntry entry = obj.getBundleStructure().getNthEntry(i);
+ for (int i=0; i < structure.getEntryCount(); i++) {
+ PropertiesFileEntry entry = structure.getNthEntry(i);
if (entry != null) {
PropertiesStructure ps = entry.getHandler().getStructure();
if (ps != null) {
@@ -524,7 +612,8 @@
}
} finally {
// finishes "atomic" undo redo action for special undo redo manager of open support
- obj.getOpenSupport().atomicUndoRedoFlag = null;
+// obj.getOpenSupport().atomicUndoRedoFlag = null;
+ structure.getOpenSupport().atomicUndoRedoFlag = null;
}
}
}//GEN-LAST:event_removeButtonActionPerformed
@@ -563,14 +652,13 @@
selectionUpdateDisabled = true;
// Starts "atomic" acion for special undo redo manager of open support.
- obj.getOpenSupport().atomicUndoRedoFlag = new Object();
-
+// obj.getOpenSupport().atomicUndoRedoFlag = new Object();
+ structure.getOpenSupport().atomicUndoRedoFlag = new Object();
String existingLocales = "";
- String comma = ",\r\n"; //NOI18N
- int count = obj.getBundleStructure().getEntryCount();
+ String comma =",\r\n";
// add key to all entries
- for (int i=0; i < count; i++) {
- PropertiesFileEntry entry = obj.getBundleStructure().getNthEntry(i);
+ for (int i=0; i < structure.getEntryCount(); i++) {
+ PropertiesFileEntry entry = structure.getNthEntry(i);
if (entry != null && !entry.getHandler().getStructure().addItem(key, value, comment)) {
existingLocales += Util.getLocaleLabel(entry) + comma;
@@ -591,10 +679,10 @@
NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(msg);
}
-
} finally {
// Finishes "atomic" undo redo action for special undo redo manager of open support.
- obj.getOpenSupport().atomicUndoRedoFlag = null;
+// obj.getOpenSupport().atomicUndoRedoFlag = null;
+ structure.getOpenSupport().atomicUndoRedoFlag = null;
selectionUpdateDisabled = false;
}
@@ -608,7 +696,7 @@
PropertiesRequestProcessor.getInstance().post(new Runnable() {
public void run() {
// Find indexes.
- int rowIndex = obj.getBundleStructure().getKeyIndexByName(key);
+ int rowIndex = structure.getKeyIndexByName(key);
if((rowIndex != -1)) {
final int row = rowIndex;
@@ -677,13 +765,20 @@
private static final String SORT_ASC_ICON = ICON_PKG + "columnSortedAsc.gif"; //NOI18N
private static final String SORT_DESC_ICON = ICON_PKG + "columnSortedDesc.gif"; //NOI18N
- private final PropertiesDataObject propDataObj;
+ private final BundleStructure bundleStructure;
private final TableCellRenderer origRenderer;
private ImageIcon iconSortAsc, iconSortDesc;
-
+
+ @Deprecated
TableViewHeaderRenderer(PropertiesDataObject propDataObj,
TableCellRenderer origRenderer) {
- this.propDataObj = propDataObj;
+ bundleStructure = propDataObj.getBundleStructure();
+ this.origRenderer = origRenderer;
+ }
+
+ TableViewHeaderRenderer(BundleStructure bundleStructure,
+ TableCellRenderer origRenderer) {
+ this.bundleStructure = bundleStructure;
this.origRenderer = origRenderer;
}
@@ -698,7 +793,7 @@
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
- BundleStructure bundleStruct = propDataObj.getBundleStructure();
+ BundleStructure bundleStruct = bundleStructure;
int sortIndex = table.convertColumnIndexToView(
bundleStruct.getSortIndex());
if (column == sortIndex) {
@@ -1003,9 +1098,10 @@
}
private void documentModified() {
- obj.setModified(true);
+ ((PropertiesTableModel)table.getModel()).getFileEntry(table.getEditingColumn()).getDataObject().setModified(true);
+// obj.setModified(true);
}
}
-
+
}
--- a/properties/src/org/netbeans/modules/properties/BundleStructure.java
+++ a/properties/src/org/netbeans/modules/properties/BundleStructure.java
@@ -44,6 +44,7 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
@@ -51,6 +52,7 @@
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
+import org.openide.filesystems.FileObject;
import org.openide.loaders.MultiDataObject.Entry;
import org.openide.util.WeakListeners;
@@ -69,7 +71,7 @@
* @author Petr Jiricka
*/
public class BundleStructure {
-
+
/**
* PropertiesDataObject
whose structure is described
* by this object
@@ -109,7 +111,10 @@
/** listens to changes on the underlying PropertyDataObject
*/
private PropertyChangeListener propListener;
-
+
+ protected BundleStructure() {
+ obj = null;
+ }
/**
* Creates a new instance describing a given
* PropertiesDataObject
.
@@ -543,6 +548,10 @@
return comparator.isAscending();
}
+ PropertiesOpen getOpenSupport() {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
/**
* Builds (or rebuilds) a sorted list of entries of the underlying
* PropertiesDataObject and a sorted list of keys gathered
@@ -551,7 +560,7 @@
* @see #entries
* @see #keyList
*/
- private void updateEntries() {
+ void updateEntries() {
Map tm = new TreeMap(
PropertiesDataObject.getSecondaryFilesComparator());
for (Entry entry : obj.secondaryEntries()) {
@@ -577,7 +586,7 @@
*
* @see #keyList
*/
- private synchronized void buildKeySet() {
+ protected synchronized void buildKeySet() {
List keyList = new ArrayList() {
public boolean equals(Object obj) {
if (!(obj instanceof ArrayList)) {
@@ -602,16 +611,18 @@
int entriesCount = getEntryCount();
for (int index = 0; index < entriesCount; index++) {
PropertiesFileEntry entry = getNthEntry(index);
- PropertiesStructure ps = entry.getHandler().getStructure();
- if (ps != null) {
- for (Iterator it = ps.allItems(); it.hasNext(); ) {
- Element.ItemElem item = it.next();
- if (item == null) {
- continue;
- }
- String key = item.getKey();
- if (key != null && !(keyList.contains(key))) {
- keyList.add(item.getKey());
+ if (entry != null) {
+ PropertiesStructure ps = entry.getHandler().getStructure();
+ if (ps != null) {
+ for (Iterator it = ps.allItems(); it.hasNext(); ) {
+ Element.ItemElem item = it.next();
+ if (item == null) {
+ continue;
+ }
+ String key = item.getKey();
+ if (key != null && !(keyList.contains(key))) {
+ keyList.add(item.getKey());
+ }
}
}
}
@@ -676,6 +687,7 @@
* @see #removePropertyBundleListener
*/
public void addPropertyBundleListener(PropertyBundleListener l) {
+ if (propBundleSupport == null) propBundleSupport = new PropertyBundleSupport(this);
propBundleSupport.addPropertyBundleListener(l);
}
@@ -707,6 +719,19 @@
);
}
+ void notifyOneFileChanged(FileObject file) {
+ // PENDING - events should be finer
+ // find out whether global key table has changed and fire a change
+ // according to that
+ List oldKeyList = keyList;
+
+ buildKeySet();
+ if (!keyList.equals(oldKeyList)) {
+ propBundleSupport.fireBundleDataChanged();
+ } else {
+ propBundleSupport.fireFileChanged(file.getName());
+ }
+ }
/**
* Notifies registered listeners of a change in a single file entry.
* Depending whether a list of keys has changed, either an event
--- a/properties/src/org/netbeans/modules/properties/MultiBundleStructure.java
+++ a/properties/src/org/netbeans/modules/properties/MultiBundleStructure.java
@@ -0,0 +1,291 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2008 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.properties;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataObject;
+import org.openide.loaders.DataObjectNotFoundException;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author alexeybutenko
+ */
+class MultiBundleStructure extends BundleStructure implements Serializable {
+
+ private transient FileObject[] files;
+ private transient PropertiesFileEntry primaryEntry;
+ private String baseName;
+
+ /** Generated Serialized Version UID. */
+ static final long serialVersionUID = 7501232754255253334L;
+
+ private transient PropertiesOpen openSupport;
+ /** Lock used for synchronization of openSupport
instance creation */
+ private final transient Object OPEN_SUPPORT_LOCK = new Object();
+
+
+ protected MultiBundleStructure() {
+// super();
+// files = null;
+// primaryEntry = null;
+// baseName = null;
+ }
+
+ public MultiBundleStructure(PropertiesDataObject obj) {
+// super(obj);
+ this.obj = obj;
+ baseName = Util.getBaseName(obj.getName());
+ }
+
+ /**
+ * Find entries according to PropertiesDataObject
+ *
+ */
+ private void findEntries() {
+ try {
+ if (obj == null) return;
+ if (!obj.isValid()) {
+ if (files.length == 1) {
+ primaryEntry = null;
+ obj = null;
+ files = null;
+ return;
+ }
+ } else {
+ obj = Util.findPrimaryDataObject(obj);
+ primaryEntry = (PropertiesFileEntry) obj.getPrimaryEntry();
+ }
+ FileObject primary = primaryEntry.getFile();
+ FileObject parent = primary.getParent();
+ List listFileObjects = new ArrayList();
+ String fName;
+ FileObject oldCandidate;
+ for (FileObject file : parent.getChildren()) {
+ fName = file.getName();
+ if (fName.equals(baseName) && file.isValid()) {
+ listFileObjects.add(0,file);
+ }
+ if (fName.indexOf(baseName) != -1) {
+ int index = fName.indexOf(PropertiesDataLoader.PRB_SEPARATOR_CHAR);
+ if (index == baseName.length()) {
+ oldCandidate = null;
+ while (index != -1) {
+ FileObject candidate = file;
+ if (candidate != null && isValidLocaleSuffix(fName.substring(index)) && oldCandidate == null && file.isValid()) {
+ listFileObjects.add(candidate);
+ oldCandidate = candidate;
+ }
+ index = fName.indexOf(PropertiesDataLoader.PRB_SEPARATOR_CHAR, index + 1);
+ }
+ }
+ }
+ }
+ files = new FileObject[listFileObjects.size()];
+ int index = 0;
+ for (FileObject file : listFileObjects) {
+ files[index++] = file;
+ }
+ primaryEntry = getNthEntry(0);
+ obj = (PropertiesDataObject) primaryEntry.getDataObject();
+ } catch (DataObjectNotFoundException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+
+ void updateEntries() {
+ findEntries();
+ if (files != null) {
+ buildKeySet();
+ }
+ }
+
+ @Override
+ public PropertiesFileEntry getNthEntry(int index) {
+ if (files == null) {
+ return super.getNthEntry(index);
+// notifyEntriesNotInitialized();
+ }
+ if (index >= 0 && index < files.length) {
+ try {
+ return (PropertiesFileEntry) ((PropertiesDataObject) DataObject.find(files[index])).getPrimaryEntry();
+ } catch (DataObjectNotFoundException ex) {
+ Exceptions.printStackTrace(ex);
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves an index of a file entry representing the given file.
+ *
+ * @param fileName simple name (without path and extension) of the
+ * primary or secondary file
+ * @return index of the entry representing a file with the given filename;
+ * or -1
if no such entry is found
+ * @exception java.lang.IllegalStateException
+ * if the list of entries has not been initialized yet
+ * @see #getEntryByFileName
+ */
+ @Override
+ public int getEntryIndexByFileName(String fileName) {
+ if (files == null) {
+ notifyEntriesNotInitialized();
+ }
+ for (int i = 0; i < getEntryCount(); i++) {
+ if (files[i].getName().equals(fileName)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Retrieves a file entry representing the given file
+ *
+ * @param fileName simple name (excl. path, incl. extension) of the
+ * primary or secondary file
+ * @return entry representing the given file;
+ * or null
if not such entry is found
+ * @exception java.lang.IllegalStateException
+ * if the list of entries has not been initialized yet
+ * @see #getEntryIndexByFileName
+ */
+ @Override
+ public PropertiesFileEntry getEntryByFileName(String fileName) {
+ int index = getEntryIndexByFileName(fileName);
+ try {
+ return (index == -1) ? null : (PropertiesFileEntry) ((PropertiesDataObject) DataObject.find(files[index])).getPrimaryEntry();
+ } catch (DataObjectNotFoundException ex) {
+ Exceptions.printStackTrace(ex);
+ return null;
+ }
+ }
+
+ /**
+ * Retrieves number of file entries.
+ *
+ * @return number of file entries
+ * @exception java.lang.IllegalStateException
+ * if the list of entries has not been initialized yet
+ */
+ @Override
+ public int getEntryCount() {
+ if (files == null) {
+ return 0;//super.getEntryCount();
+// notifyEntriesNotInitialized();
+ }
+ return files.length;
+ }
+
+ /**
+ * Throws a runtime exception with a message that the entries
+ * have not been initialized yet.
+ *
+ * @exception java.lang.IllegalStateException thrown always
+ * @see #updateEntries
+ */
+ private void notifyEntriesNotInitialized() {
+ throw new IllegalStateException(
+ "Resource Bundles: Entries not initialized"); //NOI18N
+ }
+
+ private static boolean isValidLocaleSuffix(String s) {
+ // first char is _
+ int n = s.length();
+ String s1;
+ // check first suffix - language (two chars)
+ if (n == 3 || (n > 3 && s.charAt(3) == PropertiesDataLoader.PRB_SEPARATOR_CHAR)) {
+ s1 = s.substring(1, 3).toLowerCase();
+ // language must be followed by a valid country suffix or no suffix
+ } else {
+ return false;
+ }
+ // check second suffix - country (two chars)
+ String s2;
+ if (n == 3) {
+ s2 = null;
+ } else if (n == 6 || (n > 6 && s.charAt(6) == PropertiesDataLoader.PRB_SEPARATOR_CHAR)) {
+ s2 = s.substring(4, 6).toUpperCase();
+ // country may be followed by whatever additional suffix
+ } else {
+ return false;
+ }
+
+ Set knownLanguages = new HashSet(Arrays.asList(Locale.getISOLanguages()));
+ if (!knownLanguages.contains(s1)) {
+ return false;
+ }
+
+ if (s2 != null) {
+ Set knownCountries = new HashSet(Arrays.asList(Locale.getISOCountries()));
+ if (!knownCountries.contains(s2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ @Override
+ public PropertiesOpen getOpenSupport() {
+ synchronized (OPEN_SUPPORT_LOCK) {
+ if (openSupport == null) {
+ openSupport = new PropertiesOpen(this);
+ }
+ return openSupport;
+ }
+ }
+
+ @Override
+ public int getKeyCount() {
+ try {
+ return super.getKeyCount();
+ } catch (IllegalStateException ie) {
+ return 0;
+ }
+ }
+}
--- a/properties/src/org/netbeans/modules/properties/PropertiesDataLoader.java
+++ a/properties/src/org/netbeans/modules/properties/PropertiesDataLoader.java
@@ -87,6 +87,9 @@
/** */
private static Set knownCountries;
+ /** */
+ private static boolean nestedView = false;
+
/** Creates new PropertiesDataLoader. */
public PropertiesDataLoader() {
super("org.netbeans.modules.properties.PropertiesDataObject"); // NOI18N
@@ -153,14 +156,16 @@
* corresponding to an existing file
*/
String fName = fo.getName();
- int index = fName.indexOf(PRB_SEPARATOR_CHAR);
- while (index != -1) {
- FileObject candidate = fo.getParent().getFileObject(
- fName.substring(0, index), fo.getExt());
- if (candidate != null && isValidLocaleSuffix(fName.substring(index))) {
- return candidate;
+ if (nestedView) {
+ int index = fName.indexOf(PRB_SEPARATOR_CHAR);
+ while (index != -1) {
+ FileObject candidate = fo.getParent().getFileObject(
+ fName.substring(0, index), fo.getExt());
+ if (candidate != null && isValidLocaleSuffix(fName.substring(index))) {
+ return candidate;
+ }
+ index = fName.indexOf(PRB_SEPARATOR_CHAR, index + 1);
}
- index = fName.indexOf(PRB_SEPARATOR_CHAR, index + 1);
}
return fo;
} else {
--- a/properties/src/org/netbeans/modules/properties/PropertiesDataNode.java
+++ a/properties/src/org/netbeans/modules/properties/PropertiesDataNode.java
@@ -60,7 +60,6 @@
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataNode;
import org.openide.loaders.DataObject;
-import org.openide.loaders.FileEntry;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.NodeTransfer;
@@ -103,7 +102,6 @@
public PropertiesDataNode(DataObject dataObject, Children children) {
super(dataObject, children);
setIconBaseWithExtension("org/netbeans/modules/properties/propertiesObject.png"); // NOI18N
-
dataObjectListener = new NameUpdater();
dataObject.addPropertyChangeListener(
WeakListeners.propertyChange(dataObjectListener, dataObject));
@@ -321,14 +319,15 @@
} // End of NewLocaleType class.
private static boolean containsLocale(PropertiesDataObject propertiesDataObject, Locale locale) {
- FileObject file = propertiesDataObject.getPrimaryFile();
+ FileObject file = propertiesDataObject.getBundleStructure().getNthEntry(0).getFile();
+// FileObject file = propertiesDataObject.getPrimaryFile();
String newName = file.getName() + PropertiesDataLoader.PRB_SEPARATOR_CHAR + locale;
- Iterator it = propertiesDataObject.secondaryEntries().iterator();
- while (it.hasNext()) {
- FileObject f = ((FileEntry)it.next()).getFile();
+ BundleStructure structure = propertiesDataObject.getBundleStructure();
+ for (int i = 0; i file.getName().length())
file = f;
- }
+ }
return file.getName().equals(newName);
}
}
--- a/properties/src/org/netbeans/modules/properties/PropertiesDataObject.java
+++ a/properties/src/org/netbeans/modules/properties/PropertiesDataObject.java
@@ -38,10 +38,7 @@
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
-
-
package org.netbeans.modules.properties;
-
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -60,10 +57,12 @@
import org.openide.loaders.DataNode;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectExistsException;
+import org.openide.loaders.DataObjectNotFoundException;
import org.openide.loaders.MultiDataObject;
import org.openide.nodes.Children;
import org.openide.nodes.CookieSet;
import org.openide.nodes.Node;
+import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.WeakListeners;
import static java.util.logging.Level.FINER;
@@ -79,12 +78,12 @@
/** Generated Serialized Version UID. */
static final long serialVersionUID = 4795737295255253334L;
-
+
static final Logger LOG = Logger.getLogger(PropertiesDataObject.class.getName());
/** Structural view of the dataobject */
private transient BundleStructure bundleStructure;
-
+
/** Open support for this data object. Provides editable table view on bundle. */
private transient PropertiesOpen openSupport;
@@ -94,7 +93,7 @@
// Hack due having lock on secondaries, can't override handleCopy, handleMove at all.
/** Suffix used by copying/moving dataObject. */
private transient String pasteSuffix;
-
+
/** */
private Lookup lookup;
@@ -110,7 +109,7 @@
* for the specified file
*/
public PropertiesDataObject(final FileObject primaryFile,
- final PropertiesDataLoader loader)
+ final PropertiesDataLoader loader)
throws DataObjectExistsException {
super(primaryFile, loader);
// use editor support
@@ -122,12 +121,12 @@
PropertiesEncoding getEncoding() {
return ((PropertiesDataLoader) getLoader()).getEncoding();
}
-
+
@Override
public Lookup getLookup() {
return getCookieSet().getLookup();
}
-
+
/** Initializes the object. Used by construction and deserialized. */
private void initialize() {
bundleStructure = null;
@@ -154,7 +153,7 @@
CookieSet getCookieSet0() {
return getCookieSet();
}
-
+
/** Copies primary and secondary files to new folder.
* Overrides superclass method.
* @param df the new folder
@@ -175,7 +174,7 @@
pasteSuffix = null;
}
}
-
+
/** Moves primary and secondary files to a new folder.
* Overrides superclass method.
* @param df the new folder
@@ -197,13 +196,13 @@
try {
pasteSuffix = createPasteSuffix(df);
-
+
return super.handleMove(df);
} finally {
pasteSuffix = null;
}
}
-
+
/** Gets suffix used by entries by copying/moving. */
String getPasteSuffix() {
return pasteSuffix;
@@ -215,7 +214,7 @@
void removeSecondaryEntry2(Entry fe) {
if (LOG.isLoggable(FINER)) {
LOG.finer("removeSecondaryEntry2(Entry " //NOI18N
- + FileUtil.getFileDisplayName(fe.getFile()) + ')');
+ + FileUtil.getFileDisplayName(fe.getFile()) + ')');
}
removeSecondaryEntry (fe);
}
@@ -226,26 +225,26 @@
String basicName = getPrimaryFile().getName();
DataObject[] children = folder.getChildren();
-
-
+
+
// Repeat until there is not such file name.
for(int i = 0; ; i++) {
String newName;
-
+
if (i == 0) {
newName = basicName;
} else {
newName = basicName + i;
}
boolean exist = false;
-
+
for(int j = 0; j < children.length; j++) {
if(children[j] instanceof PropertiesDataObject && newName.equals(children[j].getName())) {
exist = true;
break;
}
}
-
+
if(!exist) {
if (i == 0) {
return ""; // NOI18N
@@ -258,13 +257,24 @@
/** Returns open support. It's used by all subentries as open support too. */
public PropertiesOpen getOpenSupport() {
- synchronized(OPEN_SUPPORT_LOCK) {
- if(openSupport == null) {
- openSupport = new PropertiesOpen(this);
- }
-
- return openSupport;
- }
+// synchronized (OPEN_SUPPORT_LOCK) {
+ return ((MultiBundleStructure)getBundleStructure()).getOpenSupport();
+// PropertiesDataObject dataObject = this;
+// try {
+// dataObject = Util.findPrimaryDataObject(this);
+// } catch (DataObjectNotFoundException ex) {
+// Exceptions.printStackTrace(ex);
+// }
+// if (this == dataObject) {
+// if (openSupport == null) {
+// openSupport = new PropertiesOpen(this);
+// }
+//
+// return openSupport;
+// } else {
+// return dataObject.getOpenSupport();
+// }
+// }
}
/** Updates modification status of this dataobject from its entries. */
@@ -294,7 +304,7 @@
*
* @return the node representation for this data object
* @see DataNode
- */
+ */
@Override
protected Node createNodeDelegate () {
return new PropertiesDataNode(this);
@@ -304,15 +314,28 @@
return new PropertiesChildren();
}
+ //TODO XXX Now it is always false
boolean isMultiLocale() {
return secondaryEntries().size() > 0;
}
/** Returns a structural view of this data object */
public BundleStructure getBundleStructure() {
- if (bundleStructure == null)
- bundleStructure = new BundleStructure(this);
- return bundleStructure;
+ PropertiesDataObject dataObject = null;
+ try {
+ dataObject = Util.findPrimaryDataObject(this);
+ } catch (DataObjectNotFoundException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ if (this == dataObject) {
+ if (bundleStructure == null) {
+ bundleStructure = new MultiBundleStructure(this);
+ ((MultiBundleStructure)bundleStructure).updateEntries();
+ }
+ return bundleStructure;
+ } else {
+ return dataObject.getBundleStructure();
+ }
}
/** Comparator used for ordering secondary files, works over file names */
@@ -326,14 +349,14 @@
LOG.finer("fireNameChange()"); //NOI18N
firePropertyChange(PROP_NAME, null, null);
}
-
+
/** Deserialization. */
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initialize();
}
-
+
/** Children of this PropertiesDataObject
. */
private class PropertiesChildren extends Children.Keys {
@@ -341,13 +364,13 @@
private PropertyChangeListener propertyListener = null;
private PropertyChangeListener weakPropListener = null;
-
+
/** Constructor.*/
PropertiesChildren() {
super();
}
-
+
/** Sets all keys in the correct order */
protected void mySetKeys() {
TreeSet newKeys = new TreeSet(new Comparator() {
@@ -366,7 +389,7 @@
});
newKeys.add(getPrimaryEntry().getFile().getName());
-
+
for (Entry entry : secondaryEntries()) {
newKeys.add(entry.getFile().getName());
}
@@ -379,14 +402,14 @@
@Override
protected void addNotify () {
mySetKeys();
-
+
// listener
if(propertyListener == null) {
propertyListener = new PropertyChangeListener () {
public void propertyChange(PropertyChangeEvent evt) {
if(PROP_FILES.equals(evt.getPropertyName())) {
if (isMultiLocale()) {
- mySetKeys();
+ mySetKeys();
} else {
// These children are only used for two or more locales.
// If only default locale is left, disconnect the listener.
@@ -395,11 +418,11 @@
if (propertyListener != null) {
PropertiesDataObject.this.removePropertyChangeListener(weakPropListener);
propertyListener = null;
+ }
+ }
}
}
- }
- }
- };
+ };
weakPropListener = WeakListeners.propertyChange(propertyListener, PropertiesDataObject.this);
PropertiesDataObject.this.addPropertyChangeListener(weakPropListener);
}
@@ -419,20 +442,20 @@
if (entryName == null) {
return null;
}
-
+
PropertiesFileEntry entry = (PropertiesFileEntry)getPrimaryEntry();
-
+
if(entryName.equals(entry.getFile().getName())) {
return new Node[] {entry.getNodeDelegate()};
}
for(Iterator it = secondaryEntries().iterator();it.hasNext();) {
entry = (PropertiesFileEntry)it.next();
-
+
if (entryName.equals(entry.getFile().getName())) {
return new Node[] {entry.getNodeDelegate()};
}
}
-
+
return null;
}
--- a/properties/src/org/netbeans/modules/properties/PropertiesOpen.java
+++ a/properties/src/org/netbeans/modules/properties/PropertiesOpen.java
@@ -57,8 +57,11 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import javax.swing.Action;
import javax.swing.event.ChangeListener;
import javax.swing.JPanel;
@@ -91,7 +94,6 @@
import org.openide.util.actions.SystemAction;
import org.openide.windows.CloneableOpenSupport;
import org.openide.windows.CloneableTopComponent;
-import org.openide.util.Utilities;
import org.openide.DialogDescriptor;
import org.openide.filesystems.FileUtil;
@@ -105,8 +107,13 @@
implements OpenCookie, CloseCookie {
/** Main properties dataobject */
+ @Deprecated
PropertiesDataObject propDataObject;
-
+
+
+ private List dataObjectList;
+
+ private BundleStructure bundleStructure;
/** Listener for modificationc on dataobject, adding and removing save cookie */
PropertyChangeListener modifL;
@@ -118,16 +125,46 @@
/** Constructor */
+ @Deprecated
public PropertiesOpen(PropertiesDataObject propDataObject) {
super(new Environment(propDataObject));
this.propDataObject = propDataObject;
-
- this.propDataObject.addPropertyChangeListener(WeakListeners.propertyChange(modifL =
+
+ //PENDING Add Listeners for all DataObject from this OpenSupport
+ this.propDataObject.addPropertyChangeListener(WeakListeners.propertyChange(modifL =
new ModifiedListener(), this.propDataObject));
}
+ public PropertiesOpen(BundleStructure structure) {
+ super(new Environment(structure));
+ this.bundleStructure = structure;
+ addModifiedListeners();
+ }
+
+ private void addModifiedListeners() {
+ BundleStructure structure = bundleStructure;
+ dataObjectList = new ArrayList();
+ PropertiesDataObject dataObject;
+ modifL = new ModifiedListener();
+ for (int i=0;i map = new HashMap();
+ for (int i=0;i weakListeners;
+
/** Generated serial version UID. */
static final long serialVersionUID =2836248291419024296L;
@@ -649,12 +784,25 @@
/** Constructor.
* @param propDataObject data object we belong to */
+ @Deprecated
public PropertiesCloneableTopComponent (PropertiesDataObject propDataObject) {
this.propDataObject = propDataObject;
initialize();
}
+ private MultiBundleStructure bundleStructure;
+
+ public PropertiesCloneableTopComponent(BundleStructure structure) {
+ this.bundleStructure = (MultiBundleStructure) structure;
+ propDataObject = (PropertiesDataObject) bundleStructure.getNthEntry(0).getDataObject();
+ dataObjecs = new PropertiesDataObject[bundleStructure.getEntryCount()];
+ for (int i=0; i();
+ initialize();
+ }
/**
*/
@Override
@@ -681,14 +829,31 @@
private void initialize() {
initComponents();
setupActions();
- setActivatedNodes(new Node[] {propDataObject.getNodeDelegate()});
+ BundleStructure structure = bundleStructure;
+ PropertiesDataObject dataObject;
+ Node[] node = new Node[structure.getEntryCount()];
dataObjectListener = new NameUpdater();
- propDataObject.addPropertyChangeListener(
- WeakListeners.propertyChange(dataObjectListener,
- propDataObject));
+
+ for( int i=0; i")) { //NOI18N
@@ -894,22 +1066,30 @@
/** Gets string for tooltip. */
private String messageToolTip() {
- FileObject fo = propDataObject.getPrimaryFile();
+ FileObject fo = bundleStructure.getNthEntry(0).getFile();
return FileUtil.getFileDisplayName(fo);
}
- /**
+ /**
+ *
* Overrides superclass method. When closing last view, also close the document.
* @return {@code true} if close succeeded
*/
@Override
protected boolean closeLast () {
- if (!propDataObject.getOpenSupport().canClose ()) {
+ if (!bundleStructure.getOpenSupport().canClose ()) {
// if we cannot close the last window
return false;
}
- propDataObject.getOpenSupport().closeDocuments();
-
+ bundleStructure.getOpenSupport().closeDocuments();
+ PropertyChangeListener l;
+ for (PropertiesDataObject dataObject:dataObjecs) {
+ l = weakListeners.get(dataObject);
+ if (l!=null) {
+ dataObject.removePropertyChangeListener(l);
+ weakListeners.remove(l);
+ }
+ }
return true;
}
@@ -920,7 +1100,7 @@
*/
@Override
protected CloneableTopComponent createClonedObject () {
- return new PropertiesCloneableTopComponent(propDataObject);
+ return new PropertiesCloneableTopComponent(bundleStructure);
}
/** Gets {@code Icon}. */
@@ -950,7 +1130,7 @@
*/
@Override
public UndoRedo getUndoRedo () {
- return propDataObject.getOpenSupport().getUndoRedo();
+ return bundleStructure.getOpenSupport().getUndoRedo();
}
/** Inits the subcomponents. Sets layout for this top component and adds {@code BundleEditPanel} to it.
@@ -964,7 +1144,7 @@
c.weightx = 1.0;
c.weighty = 1.0;
c.gridwidth = GridBagConstraints.REMAINDER;
- JPanel panel = new BundleEditPanel(propDataObject, new PropertiesTableModel(propDataObject.getBundleStructure()));
+ JPanel panel = new BundleEditPanel(bundleStructure, new PropertiesTableModel(bundleStructure));
gridbag.setConstraints(panel, c);
add(panel);
}
@@ -973,7 +1153,7 @@
* is not valid.
*/
private boolean discard () {
- return propDataObject == null;
+ return bundleStructure == null;
}
@@ -985,7 +1165,7 @@
@Override
public void writeExternal (ObjectOutput out) throws IOException {
super.writeExternal(out);
- out.writeObject(propDataObject);
+ out.writeObject(bundleStructure.getNthEntry(0).getDataObject());
}
/**
@@ -998,7 +1178,12 @@
super.readExternal(in);
propDataObject = (PropertiesDataObject)in.readObject();
-
+ bundleStructure = (MultiBundleStructure) propDataObject.getBundleStructure();
+ dataObjecs = new PropertiesDataObject[bundleStructure.getEntryCount()];
+ for (int i=0;i();
initialize();
}
} // End of nested class PropertiesCloneableTopComponent.
@@ -1017,22 +1202,39 @@
// Constructor
/** Collects all UndoRedo managers from all editor support of all entries. */
+ @Deprecated
public CompoundUndoRedoManager(PropertiesDataObject obj) {
init(obj);
}
+ public CompoundUndoRedoManager(BundleStructure structure) {
+ init(structure);
+ }
/** Initialize set of managers. */
+ @Deprecated
private void init(PropertiesDataObject obj) {
- managers.add( ((PropertiesFileEntry)obj.getPrimaryEntry()).getPropertiesEditor().getUndoRedoManager());
- for (Iterator it = obj.secondaryEntries().iterator(); it.hasNext(); ) {
- managers.add( ((PropertiesFileEntry)it.next()).getPropertiesEditor().getUndoRedoManager() );
- }
+ BundleStructure structure = obj.getBundleStructure();
+ for(int i=0; i< structure.getEntryCount(); i++) {
+ managers.add(structure.getNthEntry(i).getPropertiesEditor().getUndoRedoManager());
+ }
+ }
+
+ private void init(BundleStructure structure) {
+ for(int i=0; i< structure.getEntryCount(); i++) {
+ managers.add(structure.getNthEntry(i).getPropertiesEditor().getUndoRedoManager());
+ }
}
/** Resets the managers. Used when data object has changed. */
+ @Deprecated
public synchronized void reset(PropertiesDataObject obj) {
managers.clear();
init(obj);
+ }
+
+ public synchronized void reset(BundleStructure structure) {
+ managers.clear();
+ init(structure);
}
/** Gets manager which undo edit comes to play.*/
--- a/properties/src/org/netbeans/modules/properties/PropertiesTableCellEditor.java
+++ a/properties/src/org/netbeans/modules/properties/PropertiesTableCellEditor.java
@@ -160,7 +160,7 @@
public void setValue(Object x) {
// PENDING - due to a compiler error explicitly do "super" code instead of calling super
this.value = x;
- //super.setValue(x);
+// super.setValue(x);
PropertiesTableModel.StringPair sp = (PropertiesTableModel.StringPair)x;
// set values as they deserve
--- a/properties/src/org/netbeans/modules/properties/PropertiesTableModel.java
+++ a/properties/src/org/netbeans/modules/properties/PropertiesTableModel.java
@@ -284,6 +284,14 @@
fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1, columnModelIndex));
}
+ /**
+ * Get FileEntry according to column in Table View
+ * @param column
+ * @return
+ */
+ PropertiesFileEntry getFileEntry(int column) {
+ return structure.getNthEntry(column-1);
+ }
/** Overrides superclass method. */
@Override
public String toString() {
@@ -364,8 +372,8 @@
// Note: Normal way would be use the next commented out rows, which should do in effect
// the same thing like reseting the model, but it doesn't, therefore we reset the model directly.
- //cancelEditingInTables(getDefaultCancelSelector());
- //fireTableStructureChanged();
+ cancelEditingInTables(getDefaultCancelSelector());
+ fireTableStructureChanged();
Object[] list = PropertiesTableModel.super.listenerList.getListenerList();
for(int i = 0; i < list.length; i++) {
@@ -396,9 +404,11 @@
} else if(changeType == PropertyBundleEvent.CHANGE_FILE) {
// File changed.
final int index = structure.getEntryIndexByFileName(evt.getEntryName());
+ //This mean file deleted
if (index == -1) {
- if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
- (new Exception("Changed file not found")).printStackTrace(); // NOI18N
+ fireTableStructureChanged();
+// if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
+// (new Exception("Changed file not found")).printStackTrace(); // NOI18N
return;
}
@@ -409,8 +419,8 @@
return (column == index + 1);
}
});
-
- fireTableColumnChanged(index + 1);
+// fireTableColumnChanged(index + 1);
+ fireTableStructureChanged();
} else if(changeType == PropertyBundleEvent.CHANGE_ITEM) {
// one item changed
final int index2 = structure.getEntryIndexByFileName(evt.getEntryName());
--- a/properties/src/org/netbeans/modules/properties/Util.java
+++ a/properties/src/org/netbeans/modules/properties/Util.java
@@ -45,6 +45,8 @@
import java.io.IOException;
import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Locale;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
@@ -52,8 +54,10 @@
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.Repository;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
+import org.openide.loaders.DataObjectNotFoundException;
import org.openide.loaders.FileEntry;
import org.openide.loaders.MultiDataObject;
@@ -147,14 +151,69 @@
* @see #getVariant
*/
public static String getLocaleSuffix(MultiDataObject.Entry fe) {
- MultiDataObject.Entry pe = fe.getDataObject().getPrimaryEntry();
- if (fe == pe) {
- return ""; //NOI18N
+ FileObject fo = fe.getFile();
+ String fName = fo.getName();
+ int index = fName.indexOf(PRB_SEPARATOR_CHAR);
+ FileObject po = fo;
+ while (index != -1) {
+ FileObject candidate = fo.getParent().getFileObject(
+ fName.substring(0, index), fo.getExt());
+ if (candidate != null && isValidLocaleSuffix(fName.substring(index))) {
+ po = candidate;
+ }
+ index = fName.indexOf(PRB_SEPARATOR_CHAR, index + 1);
}
- String myName = fe.getFile().getName();
- String baseName = pe.getFile().getName();
+ if (fo == po) {
+ return "";
+ }
+ String myName = fo.getName();
+ String baseName = po.getName();
assert myName.startsWith(baseName);
return myName.substring(baseName.length());
+// MultiDataObject.Entry pe = fe.getDataObject().getPrimaryEntry();
+// if (fe == pe) {
+// return ""; //NOI18N
+// }
+// String myName = fe.getFile().getName();
+// String baseName = pe.getFile().getName();
+// assert myName.startsWith(baseName);
+// return myName.substring(baseName.length());
+ }
+
+ private static boolean isValidLocaleSuffix(String s) {
+ // first char is _
+ int n = s.length();
+ String s1;
+ // check first suffix - language (two chars)
+ if (n == 3 || (n > 3 && s.charAt(3) == PropertiesDataLoader.PRB_SEPARATOR_CHAR)) {
+ s1 = s.substring(1, 3).toLowerCase();
+ // language must be followed by a valid country suffix or no suffix
+ } else {
+ return false;
+ }
+ // check second suffix - country (two chars)
+ String s2;
+ if (n == 3) {
+ s2 = null;
+ } else if (n == 6 || (n > 6 && s.charAt(6) == PropertiesDataLoader.PRB_SEPARATOR_CHAR)) {
+ s2 = s.substring(4, 6).toUpperCase();
+ // country may be followed by whatever additional suffix
+ } else {
+ return false;
+ }
+
+ HashSet knownLanguages = new HashSet(Arrays.asList(Locale.getISOLanguages()));
+ if (!knownLanguages.contains(s1)) {
+ return false;
+ }
+
+ if (s2 != null) {
+ HashSet knownCountries = new HashSet(Arrays.asList(Locale.getISOCountries()));
+ if (!knownCountries.contains(s2)) {
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -384,12 +443,19 @@
folder = FileUtil.createFolder(folder, folderPath);
fileName = fileName.substring(idx + 1);
}
- FileObject templateFO = FileUtil.getConfigFile("Templates/Other/properties.properties"); // NOI18N
+ FileSystem defaultFS = Repository.getDefault().getDefaultFileSystem();
+ FileObject templateFO = defaultFS.findResource("Templates/Other/properties.properties"); // NOI18N
DataObject template = DataObject.find(templateFO);
return (PropertiesDataObject)
template.createFromTemplate(DataFolder.findFolder(folder), fileName);
}
+ /**
+ * Create new DataObject with requested locale and notify that new locale was added
+ * @param propertiesDataObject DataObject to add locale
+ * @param locale
+ * @param copyInitialContent
+ */
public static void createLocaleFile(PropertiesDataObject propertiesDataObject,
String locale,
boolean copyInitialContent)
@@ -402,8 +468,10 @@
}
if(propertiesDataObject != null) {
- FileObject file = propertiesDataObject.getPrimaryFile();
- final String newName = file.getName() + PropertiesDataLoader.PRB_SEPARATOR_CHAR + locale;
+// FileObject file = propertiesDataObject.getPrimaryFile();
+ FileObject file = propertiesDataObject.getBundleStructure().getNthEntry(0).getFile();
+ //Default locale may be deleted
+ final String newName = getBaseName(file.getName()) + PropertiesDataLoader.PRB_SEPARATOR_CHAR + locale;
final FileObject folder = file.getParent();
// final PropertiesEditorSupport editor = (PropertiesEditorSupport)propertiesDataObject.getCookie(PropertiesEditorSupport.class);
java.util.Iterator it = propertiesDataObject.secondaryEntries().iterator();
@@ -428,6 +496,15 @@
templateFile.copy(folder, newName, PropertiesDataLoader.PROPERTIES_EXTENSION);
}
});
+ //update entries in BundleStructure
+ propertiesDataObject.getBundleStructure().updateEntries();
+ //find just created DataObject
+ PropertiesDataObject dataObject = (PropertiesDataObject) DataObject.find(folder.getFileObject(newName, PropertiesDataLoader.PROPERTIES_EXTENSION));
+ //Add it to OpenSupport
+ propertiesDataObject.getOpenSupport().addDataObject(dataObject);
+ //Notify BundleStructure that one file changed
+ propertiesDataObject.getBundleStructure().notifyOneFileChanged(folder.getFileObject(newName, PropertiesDataLoader.PROPERTIES_EXTENSION));
+// propertiesDataObject.getBundleStructure().notifyFileAdded(folder.getFileObject(newName, PropertiesDataLoader.PROPERTIES_EXTENSION));
}
} else {
// Create an empty file - creating from template via DataObject
@@ -443,4 +520,61 @@
notifyError(locale);
}
}
+
+ /**
+ *
+ * @param obj DataObject
+ * @return DataObject which represent default locale
+ * In case when default locale is absent it will return first found locale as primary,
+ * which has the same base name
+ * @throws org.openide.loaders.DataObjectNotFoundException
+ */
+ static PropertiesDataObject findPrimaryDataObject(PropertiesDataObject obj) throws DataObjectNotFoundException {
+ FileObject primary = obj.getPrimaryFile();
+ assert primary != null : "Object " + obj + " cannot have null primary file"; // NOI18N
+ String fName;
+ fName = primary.getName();
+ String baseName = getBaseName(fName);
+ FileObject parent = primary.getParent();
+ int index = fName.indexOf(PropertiesDataLoader.PRB_SEPARATOR_CHAR);
+ while (index != -1) {
+ FileObject candidate = parent.getFileObject(
+ fName.substring(0, index), primary.getExt());
+ if (candidate != null && isValidLocaleSuffix(fName.substring(index))) {
+ return (PropertiesDataObject) DataObject.find(candidate);
+ } else if (candidate == null){
+ for (FileObject file : parent.getChildren()) {
+ if (file.getName().indexOf(baseName) != -1) {
+ if (isValidLocaleSuffix(file.getName().substring(index))) {
+ return (PropertiesDataObject) DataObject.find(file);
+ }
+ }
+ }
+ }
+ index = fName.indexOf(PropertiesDataLoader.PRB_SEPARATOR_CHAR, index + 1);
+ }
+ return obj;
+ }
+
+// static BundleStructure findBundleStructure(PropertiesDataObject dataObject) {
+//
+// }
+
+ /**
+ * @param name file name
+ * @return Base name for this locale
+ */
+ static String getBaseName(String name) {
+ String baseName = null;
+ int index = name.indexOf(PropertiesDataLoader.PRB_SEPARATOR_CHAR);
+ while (index != -1) {
+ baseName = name.substring(0, index);
+ if (baseName != null && isValidLocaleSuffix(name.substring(index))) {
+ return baseName;
+ }
+ index = name.indexOf(PropertiesDataLoader.PRB_SEPARATOR_CHAR, index + 1);
+ }
+ return name;
+ }
+
}