Index: core/registry/build.xml =================================================================== RCS file: /cvs/core/registry/build.xml,v retrieving revision 1.11 diff -u -r1.11 build.xml --- core/registry/build.xml 24 Sep 2003 00:07:01 -0000 1.11 +++ core/registry/build.xml 26 Sep 2003 16:27:46 -0000 @@ -32,11 +32,12 @@ + - + Index: core/registry/manifest.mf =================================================================== RCS file: /cvs/core/registry/manifest.mf,v retrieving revision 1.6 diff -u -r1.6 manifest.mf --- core/registry/manifest.mf 11 Sep 2003 14:26:30 -0000 1.6 +++ core/registry/manifest.mf 26 Sep 2003 16:27:46 -0000 @@ -1,8 +1,9 @@ +Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.core.registry/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/core/registry/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.4 +OpenIDE-Module-Specification-Version: 1.5 OpenIDE-Module-Implementation-Version: @BUILD_NUMBER_SUBST@ OpenIDE-Module-IDE-Dependencies: IDE/1 > 3.17 OpenIDE-Module-Public-Packages: org.netbeans.api.registry.fs.* -OpenIDE-Module-Module-Dependencies: org.netbeans.modules.registry/1 > 1.5, org.netbeans.core/1 > 1.15 +OpenIDE-Module-Module-Dependencies: org.netbeans.modules.registry/1 > 1.5, org.netbeans.core/1 > 1.15, org.netbeans.modules.convertor/1 > 1.1 Index: core/registry/api/apichanges.xml =================================================================== RCS file: /cvs/core/registry/api/apichanges.xml,v retrieving revision 1.1 diff -u -r1.1 apichanges.xml --- core/registry/api/apichanges.xml 11 Sep 2003 14:26:30 -0000 1.1 +++ core/registry/api/apichanges.xml 26 Sep 2003 16:27:46 -0000 @@ -75,6 +75,23 @@ + + + + Enable use of Convertor SPI + + + + + + You may now use the Convertor SPI with the Registry over Filesystems. + If you have a (layer) folder being used as a context, simply create a + file foo.xml to create an object binding named foo. + It should be a well-formed XML file whose root (document) element is + namespace-qualified and registered using the Convertor SPI. + + + Index: core/registry/src/org/netbeans/core/registry/olddsimpl/DSUtils.java =================================================================== RCS file: /cvs/core/registry/src/org/netbeans/core/registry/olddsimpl/DSUtils.java,v retrieving revision 1.1 diff -u -r1.1 DSUtils.java --- core/registry/src/org/netbeans/core/registry/olddsimpl/DSUtils.java 15 May 2003 17:31:19 -0000 1.1 +++ core/registry/src/org/netbeans/core/registry/olddsimpl/DSUtils.java 26 Sep 2003 16:27:47 -0000 @@ -13,26 +13,30 @@ package org.netbeans.core.registry.olddsimpl; - +import java.io.IOException; +import java.io.OutputStream; import java.util.Arrays; -import java.util.Enumeration; -import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + import org.netbeans.api.registry.ContextException; -import org.netbeans.core.registry.ContextImpl; import org.netbeans.spi.registry.BasicContext; import org.netbeans.spi.registry.SpiUtils; -import org.openide.ErrorManager; +import org.netbeans.core.registry.ContextImpl; + +import org.openide.ErrorManager; import org.openide.cookies.InstanceCookie; -import org.openide.filesystems.FileObject; -import org.openide.loaders.DataObject; -import org.openide.loaders.DataObjectNotFoundException; +import org.openide.filesystems.*; +import org.openide.loaders.*; +import org.netbeans.api.convertor.ConvertorException; +import org.netbeans.api.convertor.Convertors; /** - * * @author Peter Zavadsky */ public class DSUtils { @@ -41,6 +45,14 @@ private DSUtils() { } + /** + * Try to get an object binding from a file. + * @param ctx the basic context being used + * @param folder the folder in which to look + * @param name the file name (like a binding, no ext) + * @return an object bound to it, or null + * @throws ContextException if the binding exists but there is a problem loading it + */ public static Object getObjectForFile(BasicContext ctx, FileObject folder, String name) throws ContextException { FileObject fo = findInstanceFile(folder, name); if (fo == null) { @@ -70,10 +82,10 @@ return instanceCreate (obj); } - public static Object instanceCreate (DataObject obj) throws ContextException { + private static Object instanceCreate (DataObject obj) throws ContextException { InstanceCookie ic = (InstanceCookie)obj.getCookie (InstanceCookie.class); if (ic == null) { - return null; + return instanceCreateViaConvertors(obj); } try { @@ -112,7 +124,7 @@ return null; } - public static List getInstanceExtensions() { + private static List getInstanceExtensions() { return Arrays.asList(new String[] { "instance", "xml", "settings", "shadow", "link"}); // NOI18N } @@ -164,6 +176,83 @@ } } return escaped.toString (); + } + + /** + * Try to create an instance via the Convertors API. + * @param _d a data object, which may be an XMLDataObject + * @return an instance if its root element can be converted, or null if it is not a .xml file, or it has no convertor + * @throws ContextException if it is a .xml file that cannot be parsed, or the convertor fails + */ + private static Object instanceCreateViaConvertors(DataObject _d) throws ContextException { + if (!(_d instanceof XMLDataObject)) { + return null; + } + XMLDataObject d = (XMLDataObject)_d; + Document doc; + try { + doc = d.getDocument(); + } catch (IOException ex) { + ContextException e = SpiUtils.createContextException(null, null); + ErrorManager.getDefault().annotate(e, ex); + throw e; + } catch (SAXException ex) { + ContextException e = SpiUtils.createContextException(null, null); + ErrorManager.getDefault().annotate(e, ex); + throw e; + } + Element el = doc.getDocumentElement(); + assert el.getNodeName() != null; + if (el.getNamespaceURI() != null && Convertors.canRead(el)) { + try { + return Convertors.read(el); + } catch (ConvertorException ex) { + ContextException e = SpiUtils.createContextException(null, null); + ErrorManager.getDefault().annotate(e, ErrorManager.UNKNOWN, "From " + d.getPrimaryFile(), null, ex, null); + throw e; + } catch (Exception e) { + assert false : e + " from " + d.getPrimaryFile(); + return null; + } + } else { + return null; + } + } + + /** + * Make a binding for an object to a file. + * @param folder the folder to store it in + * @param name the name of the binding (file basename) + * @param o a structured object to store + * @throws IOException if there is a problem storing it + */ + public static void bindObjectToFile(DataFolder folder, final String name, final Object o) throws IOException { + if (Convertors.canWrite(o)) { + // XXX delete other kinds of bindings first? very unlikely to matter... + final FileObject fileFolder = folder.getPrimaryFile(); + fileFolder.getFileSystem().runAtomicAction(new FileSystem.AtomicAction() { + public void run() throws IOException { + FileObject xml = fileFolder.getFileObject(name, "xml"); + if (xml == null) { + xml = fileFolder.createData(name, "xml"); + } + FileLock l = xml.lock(); + try { + OutputStream os = xml.getOutputStream(l); + try { + Convertors.write(os, o); + } finally { + os.close(); + } + } finally { + l.releaseLock(); + } + } + }); + } else { + // Fallback to old-style storage, e.g. .settings with . + InstanceDataObject.create(folder, name, o, null); + } } } Index: core/registry/src/org/netbeans/core/registry/olddsimpl/ObjectBindings.java =================================================================== RCS file: /cvs/core/registry/src/org/netbeans/core/registry/olddsimpl/ObjectBindings.java,v retrieving revision 1.6 diff -u -r1.6 ObjectBindings.java --- core/registry/src/org/netbeans/core/registry/olddsimpl/ObjectBindings.java 24 Sep 2003 16:51:04 -0000 1.6 +++ core/registry/src/org/netbeans/core/registry/olddsimpl/ObjectBindings.java 26 Sep 2003 16:27:47 -0000 @@ -25,15 +25,12 @@ import org.netbeans.api.registry.Context; import org.netbeans.api.registry.ContextException; import org.netbeans.api.registry.ObjectRef; -import org.netbeans.core.projects.SessionManager; -import org.netbeans.core.registry.ContextImpl; import org.netbeans.spi.registry.BasicContext; import org.netbeans.spi.registry.SpiUtils; import org.openide.ErrorManager; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem; import org.openide.loaders.DataFolder; -import org.openide.loaders.InstanceDataObject; public class ObjectBindings { @@ -198,7 +195,7 @@ folder.setAttribute(PRIMITIVE_BINDING_PREFIX+name, null); } // and now creating object binding: - InstanceDataObject.create(dataFolder, name, object, null); + DSUtils.bindObjectToFile(dataFolder, name, object); } } }