This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 91665
Collapse All | Expand All

(-)a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/resources/layer.xml (+1 lines)
Lines 200-205 made subject to such option by the copyr Link Here
200
            <file name="templateDataNode.java" url="../wizard/loader/templateDataNode.javx"/>
200
            <file name="templateDataNode.java" url="../wizard/loader/templateDataNode.javx"/>
201
            <file name="templateDataObject.java" url="../wizard/loader/templateDataObject.javx"/>
201
            <file name="templateDataObject.java" url="../wizard/loader/templateDataObject.javx"/>
202
            <file name="templateDataObjectWithLookup.java" url="../wizard/loader/templateDataObjectWithLookup.javx"/>
202
            <file name="templateDataObjectWithLookup.java" url="../wizard/loader/templateDataObjectWithLookup.javx"/>
203
            <file name="templateDataObjectInLayer.java" url="../wizard/loader/templateDataObjectInLayer.javx"/>
203
            <file name="templateNew1" url="../wizard/loader/templateNew1"/>
204
            <file name="templateNew1" url="../wizard/loader/templateNew1"/>
204
            <file name="templateNew2" url="../wizard/loader/templateNew2"/>
205
            <file name="templateNew2" url="../wizard/loader/templateNew2"/>
205
            <file name="templateresolver.xml" url="../wizard/loader/templateresolver.xml"/>
206
            <file name="templateresolver.xml" url="../wizard/loader/templateresolver.xml"/>
(-)a/apisupport.project/src/org/netbeans/modules/apisupport/project/ui/wizard/loader/NewLoaderIterator.java (-31 / +70 lines)
Lines 44-49 import java.io.CharConversionException; Link Here
44
import java.io.CharConversionException;
44
import java.io.CharConversionException;
45
import java.io.File;
45
import java.io.File;
46
import java.io.IOException;
46
import java.io.IOException;
47
import java.net.MalformedURLException;
48
import java.net.URL;
47
import java.util.ArrayList;
49
import java.util.ArrayList;
48
import java.util.Arrays;
50
import java.util.Arrays;
49
import java.util.Collections;
51
import java.util.Collections;
Lines 65-70 import org.openide.loaders.DataFolder; Link Here
65
import org.openide.loaders.DataFolder;
67
import org.openide.loaders.DataFolder;
66
import org.openide.loaders.DataObject;
68
import org.openide.loaders.DataObject;
67
import org.openide.modules.SpecificationVersion;
69
import org.openide.modules.SpecificationVersion;
70
import org.openide.util.Exceptions;
68
import org.openide.util.NbBundle;
71
import org.openide.util.NbBundle;
69
import org.openide.xml.XMLUtil;
72
import org.openide.xml.XMLUtil;
70
73
Lines 178-183 final class NewLoaderIterator extends Ba Link Here
178
    
181
    
179
    public static void generateFileChanges(DataModel model) {
182
    public static void generateFileChanges(DataModel model) {
180
        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());
183
        CreatedModifiedFiles fileChanges = new CreatedModifiedFiles(model.getProject());
184
185
        boolean loaderlessObject;
186
        boolean lookupReadyObject;
187
        try {
188
            SpecificationVersion current = model.getModuleInfo().getDependencyVersion("org.openide.loaders");
189
            loaderlessObject = current.compareTo(new SpecificationVersion("7.1")) >= 0; // NOI18N
190
            lookupReadyObject = current.compareTo(new SpecificationVersion("6.0")) >= 0; // NOI18N
191
        } catch (IOException ex) {
192
            Logger.getLogger(NewLoaderIterator.class.getName()).log(Level.INFO, null, ex);
193
            loaderlessObject = false;
194
            lookupReadyObject = false;
195
        }
181
        
196
        
182
        String namePrefix = model.getPrefix();
197
        String namePrefix = model.getPrefix();
183
        String packageName = model.getPackageName();
198
        String packageName = model.getPackageName();
Lines 191-216 final class NewLoaderIterator extends Ba Link Here
191
        
206
        
192
        // Copy action icon
207
        // Copy action icon
193
        String origIconPath = model.getIconPath();
208
        String origIconPath = model.getIconPath();
209
        String relativeIconPath;
194
        if (origIconPath != null && new File(origIconPath).exists()) {
210
        if (origIconPath != null && new File(origIconPath).exists()) {
195
            String relativeIconPath = model.addCreateIconOperation(fileChanges, origIconPath);
211
            relativeIconPath = model.addCreateIconOperation(fileChanges, origIconPath);
196
            replaceTokens.put("IMAGESNIPPET", formatImageSnippet(relativeIconPath));//NOI18N
212
            replaceTokens.put("IMAGESNIPPET", formatImageSnippet(relativeIconPath));//NOI18N
197
            replaceTokens.put("ICONPATH", relativeIconPath);//NOI18N
213
            replaceTokens.put("ICONPATH", relativeIconPath);//NOI18N
198
            replaceTokens.put("COMMENTICON", "");//NOI18N
214
            replaceTokens.put("COMMENTICON", "");//NOI18N
199
            
200
        } else {
215
        } else {
201
            replaceTokens.put("IMAGESNIPPET", formatImageSnippet(null)); //NOI18N
216
            replaceTokens.put("IMAGESNIPPET", formatImageSnippet(null)); //NOI18N
202
            replaceTokens.put("ICONPATH", "SET/PATH/TO/ICON/HERE"); //NOI18N
217
            replaceTokens.put("ICONPATH", "SET/PATH/TO/ICON/HERE"); //NOI18N
203
            replaceTokens.put("COMMENTICON", "//");//NOI18N
218
            replaceTokens.put("COMMENTICON", "//");//NOI18N
219
            relativeIconPath = null;
204
        }
220
        }
205
        
221
        
206
        // 1. create dataloader file
222
        FileObject template;
207
        String loaderName = model.getDefaultPackagePath(namePrefix + "DataLoader.java", false); // NOI18N
223
        if (!loaderlessObject) {
208
        // XXX use nbresloc URL protocol rather than NewLoaderIterator.class.getResource(...):
224
            // 1. create dataloader file
209
        FileObject template = CreatedModifiedFiles.getTemplate("templateDataLoader.java");//NOI18N
225
            String loaderName = model.getDefaultPackagePath(namePrefix + "DataLoader.java", false); // NOI18N
210
        fileChanges.add(fileChanges.createFileWithSubstitutions(loaderName, template, replaceTokens));
226
            // XXX use nbresloc URL protocol rather than NewLoaderIterator.class.getResource(...):
211
        String loaderInfoName = model.getDefaultPackagePath(namePrefix + "DataLoaderBeanInfo.java", false); // NOI18N
227
            template = CreatedModifiedFiles.getTemplate("templateDataLoader.java");//NOI18N
212
        template = CreatedModifiedFiles.getTemplate("templateDataLoaderBeanInfo.java");//NOI18N
228
            fileChanges.add(fileChanges.createFileWithSubstitutions(loaderName, template, replaceTokens));
213
        fileChanges.add(fileChanges.createFileWithSubstitutions(loaderInfoName, template, replaceTokens));
229
            String loaderInfoName = model.getDefaultPackagePath(namePrefix + "DataLoaderBeanInfo.java", false); // NOI18N
230
            template = CreatedModifiedFiles.getTemplate("templateDataLoaderBeanInfo.java");//NOI18N
231
            fileChanges.add(fileChanges.createFileWithSubstitutions(loaderInfoName, template, replaceTokens));
232
        }
214
        
233
        
215
        // 2. dataobject file
234
        // 2. dataobject file
216
        final boolean isEditable = Pattern.matches("(application/([a-zA-Z0-9_.-])*\\+xml|text/([a-zA-Z0-9_.+-])*)", //NOI18N
235
        final boolean isEditable = Pattern.matches("(application/([a-zA-Z0-9_.-])*\\+xml|text/([a-zA-Z0-9_.+-])*)", //NOI18N
Lines 229-252 final class NewLoaderIterator extends Ba Link Here
229
        
248
        
230
        String doName = model.getDefaultPackagePath(namePrefix + "DataObject.java", false); // NOI18N
249
        String doName = model.getDefaultPackagePath(namePrefix + "DataObject.java", false); // NOI18N
231
        template = null;
250
        template = null;
232
        try {
251
        if (loaderlessObject) {
233
            SpecificationVersion current = model.getModuleInfo().getDependencyVersion("org.openide.loaders");
252
            template = CreatedModifiedFiles.getTemplate("templateDataObjectInLayer.java");//NOI18N
234
            SpecificationVersion desired = new SpecificationVersion("6.0"); // NOI18N
253
        } else {
235
            if (current.compareTo(desired) >= 0) {
254
            if (lookupReadyObject) {
236
                template = CreatedModifiedFiles.getTemplate("templateDataObjectWithLookup.java");//NOI18N
255
                template = CreatedModifiedFiles.getTemplate("templateDataObjectWithLookup.java");//NOI18N
237
            }
256
            }
238
        } catch (IOException ex) {
239
            Logger.getLogger(NewLoaderIterator.class.getName()).log(Level.INFO, null, ex);
240
        }
257
        }
241
        if (template == null) {
258
        if (template == null) {
242
            template = CreatedModifiedFiles.getTemplate("templateDataObject.java");//NOI18N
259
            template = CreatedModifiedFiles.getTemplate("templateDataObject.java");//NOI18N
243
        }
260
        }
244
        fileChanges.add(fileChanges.createFileWithSubstitutions(doName, template, replaceTokens));
261
        fileChanges.add(fileChanges.createFileWithSubstitutions(doName, template, replaceTokens));
245
        
262
        
246
        // 3. node file
263
        if (!loaderlessObject) {
247
        String nodeName = model.getDefaultPackagePath(namePrefix + "DataNode.java", false); // NOI18N
264
            // 3. node file
248
        template = CreatedModifiedFiles.getTemplate("templateDataNode.java");//NOI18N
265
            String nodeName = model.getDefaultPackagePath(namePrefix + "DataNode.java", false); // NOI18N
249
        fileChanges.add(fileChanges.createFileWithSubstitutions(nodeName, template, replaceTokens));
266
            template = CreatedModifiedFiles.getTemplate("templateDataNode.java");//NOI18N
267
            fileChanges.add(fileChanges.createFileWithSubstitutions(nodeName, template, replaceTokens));
268
        }
250
        
269
        
251
        // 4. mimetyperesolver file
270
        // 4. mimetyperesolver file
252
        template = CreatedModifiedFiles.getTemplate("templateresolver.xml");//NOI18N
271
        template = CreatedModifiedFiles.getTemplate("templateresolver.xml");//NOI18N
Lines 273-290 final class NewLoaderIterator extends Ba Link Here
273
        fileChanges.add(fileChanges.bundleKey(bundlePath, "LBL_" + namePrefix + "_loader_name",  // NOI18N
292
        fileChanges.add(fileChanges.bundleKey(bundlePath, "LBL_" + namePrefix + "_loader_name",  // NOI18N
274
                NbBundle.getMessage(NewLoaderIterator.class, "LBL_LoaderName", namePrefix))); //NOI18N
293
                NbBundle.getMessage(NewLoaderIterator.class, "LBL_LoaderName", namePrefix))); //NOI18N
275
        
294
        
276
        // 7. register manifest entry
295
        if (loaderlessObject) {
277
        boolean isXml = Pattern.matches("(application/([a-zA-Z0-9_.-])*\\+xml|text/([a-zA-Z0-9_.-])*\\+xml)", //NOI18N
296
            // 7. register in layer
278
                mime);
297
            String path = "Loaders/" + mime + "/Factories/" + namePrefix + "DataLoader.instance";
279
        String installBefore = null;
298
            Map<String,Object> attrs = new HashMap<String, Object>();
280
        if (isXml) {
299
            attrs.put("instanceCreate", "methodvalue:org.openide.loaders.DataLoaderPool.factory"); //NOI18N
281
            installBefore = "org.openide.loaders.XMLDataObject, org.netbeans.modules.xml.XMLDataObject"; //NOI18N
300
            attrs.put("dataObjectClass", packageName + "." + namePrefix + "DataObject"); //NOI18N
301
            attrs.put("mimeType", mime); //NOI18N
302
            if (relativeIconPath != null) {
303
                try {
304
                    URL url = new URL("nbresloc:/" + relativeIconPath); //NOI18N
305
                    attrs.put("SystemFileSystem.icon", url); //NOI18N
306
                } catch (MalformedURLException ex) {
307
                    throw new IllegalStateException(ex);
308
                }
309
            }
310
            fileChanges.add(
311
                fileChanges.createLayerEntry(path, null, null, null, attrs)
312
            );
313
        } else {
314
            // 7. register manifest entry
315
            boolean isXml = Pattern.matches("(application/([a-zA-Z0-9_.-])*\\+xml|text/([a-zA-Z0-9_.-])*\\+xml)", //NOI18N
316
                    mime);
317
            String installBefore = null;
318
            if (isXml) {
319
                installBefore = "org.openide.loaders.XMLDataObject, org.netbeans.modules.xml.XMLDataObject"; //NOI18N
320
            }
321
322
            fileChanges.add(fileChanges.addLoaderSection(packageName.replace('.', '/')  + "/" + namePrefix + "DataLoader", installBefore)); // NOI18N
323
324
            // 7a. create matching test registration for convenience (#73202)
325
            fileChanges.add(fileChanges.addLookupRegistration("org.openide.loaders.DataLoader", packageName + '.' + namePrefix + "DataLoader", true)); // NOI18N
282
        }
326
        }
283
        
284
        fileChanges.add(fileChanges.addLoaderSection(packageName.replace('.', '/')  + "/" + namePrefix + "DataLoader", installBefore)); // NOI18N
285
286
        // 7a. create matching test registration for convenience (#73202)
287
        fileChanges.add(fileChanges.addLookupRegistration("org.openide.loaders.DataLoader", packageName + '.' + namePrefix + "DataLoader", true)); // NOI18N
288
        
327
        
289
        //8. create layerfile actions subsection
328
        //8. create layerfile actions subsection
290
        
329
        
(-)54f623a0e6e1 (+36 lines)
Added Link Here
1
<#assign licenseFirst = "/*">
2
<#assign licensePrefix = " * ">
3
<#assign licenseLast = " */">
4
<#include "../Licenses/license-${project.license}.txt">
5
6
package ${PACKAGENAME};
7
8
import java.io.IOException;
9
import org.openide.filesystems.FileObject;
10
import org.openide.loaders.DataNode;
11
import org.openide.loaders.DataObjectExistsException;
12
import org.openide.loaders.MultiDataObject;
13
import org.openide.loaders.MultiFileLoader;
14
import org.openide.nodes.CookieSet;
15
import org.openide.nodes.Node;
16
import org.openide.nodes.Children;
17
import org.openide.util.Lookup;
18
${EDITOR_SUPPORT_IMPORT}
19
20
public class ${PREFIX}DataObject extends MultiDataObject {
21
22
    public ${PREFIX}DataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
23
        super(pf, loader);
24
${EDITOR_SUPPORT_SNIPPET}
25
    }
26
27
    @Override
28
    protected Node createNodeDelegate() {
29
        return new DataNode(this, Children.LEAF, getLookup());
30
    }
31
32
    @Override
33
    public Lookup getLookup() {
34
        return getCookieSet().getLookup();
35
    }
36
}
(-)a/openide.loaders/apichanges.xml (+18 lines)
Lines 106-111 is the proper place. Link Here
106
<!-- ACTUAL CHANGES BEGIN HERE: -->
106
<!-- ACTUAL CHANGES BEGIN HERE: -->
107
107
108
  <changes>
108
  <changes>
109
     <change id="factory">
110
        <api name="loaders"/>
111
        <summary>DataObjects without DataLoaders</summary>
112
        <version major="7" minor="1"/>
113
        <date day="11" month="6" year="2008"/>
114
        <author login="jtulach"/>
115
        <compatibility addition="yes" binary="compatible" />
116
        <description>
117
        <p>
118
            There is new method to register new DataObject types without
119
            the need to write own DataLoader. Use
120
            <a href="@TOP@/org/openide/loaders/DataLoaderPool.html#factory(java.lang.Class,%20java.lang.String,%20java.awt.Image)">
121
                DataLoaderPool.factory</a> method.
122
        </p>
123
        </description>
124
        <class package="org.openide.loaders" name="DataLoaderPool" />
125
        <issue number="91665"/>
126
    </change>
109
     <change id="layer.registration">
127
     <change id="layer.registration">
110
        <api name="loaders"/>
128
        <api name="loaders"/>
111
        <summary>Loaders are registered in layer files</summary>
129
        <summary>Loaders are registered in layer files</summary>
(-)a/openide.loaders/manifest.mf (-1 / +1 lines)
Lines 1-6 Manifest-Version: 1.0 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.openide.loaders
2
OpenIDE-Module: org.openide.loaders
3
OpenIDE-Module-Specification-Version: 7.0
3
OpenIDE-Module-Specification-Version: 7.1
4
OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties
5
OpenIDE-Module-Recommends: org.netbeans.modules.templates.v1_0
5
OpenIDE-Module-Recommends: org.netbeans.modules.templates.v1_0
6
AutoUpdate-Essential-Module: true
6
AutoUpdate-Essential-Module: true
(-)a/openide.loaders/src/org/openide/loaders/DataLoaderPool.java (-6 / +45 lines)
Lines 41-47 Link Here
41
41
42
package org.openide.loaders;
42
package org.openide.loaders;
43
43
44
import java.awt.Image;
44
import java.io.*;
45
import java.io.*;
46
import java.lang.reflect.Constructor;
47
import java.lang.reflect.InvocationTargetException;
45
import java.util.*;
48
import java.util.*;
46
import java.util.logging.Level;
49
import java.util.logging.Level;
47
import java.util.logging.Logger;
50
import java.util.logging.Logger;
Lines 476-482 implements java.io.Serializable { Link Here
476
        Enumeration<? extends DataObject.Factory> en = allLoaders (fo);
479
        Enumeration<? extends DataObject.Factory> en = allLoaders (fo);
477
        while (en.hasMoreElements ()) {
480
        while (en.hasMoreElements ()) {
478
            DataObject.Factory l = en.nextElement ();
481
            DataObject.Factory l = en.nextElement ();
479
            DataObject obj = l.findDataObject (fo, recognized);
482
            DataObject obj;
483
            if (l instanceof DataLoader) {
484
                obj = l.findDataObject (fo, recognized);
485
            } else {
486
                obj = DataObjectPool.handleFindDataObject(l, fo, recognized);
487
            }
480
            if (!recognized.isEmpty()) {
488
            if (!recognized.isEmpty()) {
481
                for (FileObject f : recognized) {
489
                for (FileObject f : recognized) {
482
                    r.markRecognized(f);
490
                    r.markRecognized(f);
Lines 575-581 implements java.io.Serializable { Link Here
575
        }
583
        }
576
        return null;
584
        return null;
577
    }
585
    }
578
    
586
587
    /** Factory method to create default implementation of a factory for
588
     * data objects. It takes the class of the <code>DataObject</code> and
589
     * is ready to call its constructor. The constructor needs to take two
590
     * arguments: FileObject and MultiDataLoader. It can throw IOException as
591
     * is usual among DataObject constructors.
592
     * <p>
593
     * You can also invoke this method from a layer by following definition:
594
     * <pre>
595
     * &lt;file name="nameofyourfile.instance"&gt;
596
     *   &lt;attr name="instanceCreate" methodvalue="org.openide.loaders.DataLoaderPool.factory"/&gt;
597
     *   &lt;attr name="dataObjectClass" stringvalue="org.your.pkg.YourDataObject"/&gt;
598
     *   &lt;attr name="mimeType" stringvalue="yourmime/type"/&gt;
599
     *   &lt;attr name="SystemFileSystem.localizingIcon" stringvalue="org/your/pkg/YourDataObject.png"/&gt;
600
     * &lt;/file&gt;
601
     * </pre>
602
     * @param clazz the class of the data object to create. Must have appropriate
603
     *    constructor.
604
     * @param mimeType the mime type associated with the object, used for 
605
     *    example to create the right actions for the object's node
606
     * @param image icon to use by default for nodes representing data objects
607
     *    created with this factory
608
     * @return factory to be registered in <code>Loaders/mime/type/Factories</code>
609
     *    in some module layer file
610
     * @since 7.1
611
     */
612
    public static <T extends DataObject> DataObject.Factory factory(
613
        Class<T> dataObjectClass, String mimeType, Image image
614
    ) {
615
        return new MimeFactory<T>(dataObjectClass, mimeType, image, null);
616
    }
617
    static <T extends DataObject> DataObject.Factory factory(
618
        FileObject fo
619
    ) throws ClassNotFoundException {
620
        return MimeFactory.layer(fo);
621
    }
579
    
622
    
580
    /** Lazy getter for system loaders.
623
    /** Lazy getter for system loaders.
581
     */
624
     */
Lines 801-811 private static class InstanceLoader exte Link Here
801
        };
844
        };
802
    }
845
    }
803
} // end of InstanceLoader
846
} // end of InstanceLoader
804
805
806
807
    
847
    
808
809
/** Loader for file objects not recognized by any other loader */
848
/** Loader for file objects not recognized by any other loader */
810
private static final class DefaultLoader extends MultiFileLoader {
849
private static final class DefaultLoader extends MultiFileLoader {
811
    static final long serialVersionUID =-6761887227412396555L;
850
    static final long serialVersionUID =-6761887227412396555L;
(-)a/openide.loaders/src/org/openide/loaders/DataNode.java (-2 / +20 lines)
Lines 246-251 public class DataNode extends AbstractNo Link Here
246
         }
246
         }
247
         return super.getHtmlDisplayName();
247
         return super.getHtmlDisplayName();
248
     }    
248
     }    
249
     
250
     private java.awt.Image getImageFromFactory(int type) {
251
         MimeFactory<?> fact = getLookup().lookup(MimeFactory.class);
252
         return fact != null ? fact.getImage(type) : null;
253
     }
249
254
250
    /** Get the displayed icon for this node.
255
    /** Get the displayed icon for this node.
251
     * A filesystem may {@link org.openide.filesystems.FileSystem#getStatus specially alter} this.
256
     * A filesystem may {@link org.openide.filesystems.FileSystem#getStatus specially alter} this.
Lines 254-261 public class DataNode extends AbstractNo Link Here
254
     * @param type the icon type from {@link java.beans.BeanInfo}
259
     * @param type the icon type from {@link java.beans.BeanInfo}
255
     * @return the desired icon
260
     * @return the desired icon
256
    */
261
    */
262
    @Override
257
    public java.awt.Image getIcon (int type) {
263
    public java.awt.Image getIcon (int type) {
258
        java.awt.Image img = super.getIcon (type);
264
        java.awt.Image img = getImageFromFactory(type);
265
        if (img == null) {
266
            img = super.getIcon (type);
267
        }
259
268
260
        try {
269
        try {
261
            img = obj.getPrimaryFile ().getFileSystem ().getStatus ().annotateIcon (img, type, new LazyFilesSet());
270
            img = obj.getPrimaryFile ().getFileSystem ().getStatus ().annotateIcon (img, type, new LazyFilesSet());
Lines 273-280 public class DataNode extends AbstractNo Link Here
273
    * @param type the icon type from {@link java.beans.BeanInfo}
282
    * @param type the icon type from {@link java.beans.BeanInfo}
274
    * @return the desired icon
283
    * @return the desired icon
275
    */
284
    */
285
    @Override
276
    public java.awt.Image getOpenedIcon (int type) {
286
    public java.awt.Image getOpenedIcon (int type) {
277
        java.awt.Image img = super.getOpenedIcon(type);
287
        java.awt.Image img = getImageFromFactory(type);
288
        if (img == null) {
289
            img = super.getOpenedIcon(type);
290
        }
278
291
279
        try {
292
        try {
280
            img = obj.getPrimaryFile ().getFileSystem ().getStatus ().annotateIcon (img, type, new LazyFilesSet());
293
            img = obj.getPrimaryFile ().getFileSystem ().getStatus ().annotateIcon (img, type, new LazyFilesSet());
Lines 351-356 public class DataNode extends AbstractNo Link Here
351
364
352
        if (systemActions != null) {
365
        if (systemActions != null) {
353
            return systemActions;
366
            return systemActions;
367
        }
368
369
        MimeFactory<?> mime = getLookup().lookup(MimeFactory.class);
370
        if (mime != null) {
371
            return mime.getActions();
354
        }
372
        }
355
373
356
        return obj.getLoader ().getSwingActions ();
374
        return obj.getLoader ().getSwingActions ();
(-)a/openide.loaders/src/org/openide/loaders/DataObjectPool.java (+20 lines)
Lines 156-161 implements ChangeListener { Link Here
156
            getPOOL ().enterRecognition(fo);
156
            getPOOL ().enterRecognition(fo);
157
            
157
            
158
            ret = loader.handleFindDataObject (fo, rec);
158
            ret = loader.handleFindDataObject (fo, rec);
159
        } finally {
160
            exitAllowConstructor (prev);
161
        }
162
        
163
        return ret;
164
    }
165
    
166
    /** Calls into one loader. Setups security condition to allow DataObject ocnstructor
167
     * to succeed.
168
     */
169
    public static DataObject handleFindDataObject (DataObject.Factory factory, FileObject fo, Set<? super FileObject> rec) 
170
    throws java.io.IOException {
171
        DataObject ret;
172
        
173
        Collection<Item> prev = enterAllowContructor();
174
        try {
175
            // make sure this thread is allowed to recognize
176
            getPOOL ().enterRecognition(fo);
177
            
178
            ret = factory.findDataObject (fo, rec);
159
        } finally {
179
        } finally {
160
            exitAllowConstructor (prev);
180
            exitAllowConstructor (prev);
161
        }
181
        }
(-)54f623a0e6e1 (+156 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
package org.openide.loaders;
42
43
import java.awt.Image;
44
import java.io.IOException;
45
import java.lang.reflect.Constructor;
46
import java.lang.reflect.InvocationTargetException;
47
import java.util.Collections;
48
import java.util.Set;
49
import javax.swing.Action;
50
import org.openide.filesystems.FileObject;
51
import org.openide.filesystems.FileStateInvalidException;
52
import org.openide.filesystems.Repository;
53
import org.openide.util.Exceptions;
54
import org.openide.util.Lookup;
55
import org.openide.util.Utilities;
56
57
/** Default DataObject.Factory implementation.
58
 * 
59
 * @author Jaroslav Tulach
60
 * @param <T> type of DataObject to create
61
 */
62
class MimeFactory<T extends DataObject> implements DataObject.Factory {
63
    final Class<? extends T> clazz;
64
    final Constructor<? extends T> factory;
65
    final String mimeType;
66
    Image img;
67
    final FileObject fo;
68
69
    public MimeFactory(Class<? extends T> clazz, String mimeType, Image img, FileObject fo) {
70
        super();
71
        this.clazz = clazz;
72
        this.mimeType = mimeType;
73
        this.img = img;
74
        try {
75
            this.factory = clazz.getConstructor(FileObject.class, MultiFileLoader.class);
76
            this.factory.setAccessible(true);
77
        } catch (NoSuchMethodException ex) {
78
            throw (IllegalStateException) new IllegalStateException(ex.getMessage()).initCause(ex);
79
        }
80
        this.fo = fo;
81
    }
82
    
83
    public static MimeFactory<DataObject> layer(FileObject fo) throws ClassNotFoundException {
84
        String className = (String) fo.getAttribute("dataObjectClass"); // NOI18N
85
        if (className == null) {
86
            throw new IllegalStateException("No attribute dataObjectClass for " + fo);
87
        }
88
        String mimeType = (String)fo.getAttribute("mimeType"); // NOI18N
89
        
90
        ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
91
        if (l == null) {
92
            l = Thread.currentThread().getContextClassLoader();
93
        }
94
        if (l == null) {
95
            l = MimeFactory.class.getClassLoader();
96
        }
97
        Class<? extends DataObject> clazz = l.loadClass(className).asSubclass(DataObject.class);
98
        return new MimeFactory<DataObject>(clazz, mimeType, null, fo);
99
    }
100
101
    public DataObject findDataObject(FileObject fo, Set<? super FileObject> recognized) throws IOException {
102
        DataObject obj = null;
103
        Exception e = null;
104
        try {
105
            obj = factory.newInstance(fo, DataLoaderPool.getDefaultFileLoader());
106
        } catch (InstantiationException ex) {
107
            e = ex;
108
        } catch (IllegalAccessException ex) {
109
            e = ex;
110
        } catch (IllegalArgumentException ex) {
111
            e = ex;
112
        } catch (InvocationTargetException ex) {
113
            if (ex.getTargetException() instanceof IOException) {
114
                throw (IOException)ex.getTargetException();
115
            }
116
            e = ex;
117
        }
118
        if (obj == null) {
119
            throw (IOException) new IOException(e.getMessage()).initCause(e);
120
        }
121
        if (obj instanceof MultiDataObject) {
122
            MultiDataObject mdo = (MultiDataObject) obj;
123
            mdo.getCookieSet().assign(DataObject.Factory.class, this);
124
        }
125
        return obj;
126
    }
127
    
128
    final Image getImage(int type) {
129
        if (img == null && fo != null) {
130
            img = Utilities.loadImage("org/openide/loaders/empty.gif", true); // NOI18N
131
            try {
132
                img = fo.getFileSystem().getStatus().annotateIcon(img, type, Collections.singleton(fo));
133
            } catch (FileStateInvalidException ex) {
134
                Exceptions.printStackTrace(ex);
135
            }
136
        }
137
        return img;
138
    }
139
    
140
    final Action[] getActions() {
141
        FileObject actions = Repository.getDefault().getDefaultFileSystem().findResource(
142
            "Loaders/" + mimeType + "/Actions"
143
        );
144
        if (actions != null) {
145
            DataFolder folder = DataFolder.findFolder(actions);
146
            try {
147
                return (Action[]) new DataLdrActions(folder, null).instanceCreate();
148
            } catch (IOException ex) {
149
                Exceptions.printStackTrace(ex);
150
            } catch (ClassNotFoundException ex) {
151
                Exceptions.printStackTrace(ex);
152
            }
153
        }
154
        return DataLoaderPool.getDefaultFileLoader().getSwingActions();
155
    }
156
}
(-)a/openide.loaders/test/unit/src/org/openide/loaders/DataLoaderInLayerTest.java (-1 / +131 lines)
Lines 42-53 package org.openide.loaders; Link Here
42
package org.openide.loaders;
42
package org.openide.loaders;
43
43
44
44
45
import java.awt.Image;
46
import java.awt.Toolkit;
47
import java.awt.image.ImageObserver;
45
import org.openide.filesystems.*;
48
import org.openide.filesystems.*;
46
import java.io.IOException;
49
import java.io.IOException;
47
import java.util.*;
50
import java.util.*;
48
import org.netbeans.junit.*;
51
import org.netbeans.junit.*;
49
import java.beans.PropertyChangeListener;
52
import java.beans.PropertyChangeListener;
53
import java.lang.ref.Reference;
54
import java.lang.ref.WeakReference;
55
import java.net.URL;
56
import javax.swing.Action;
50
import junit.framework.Test;
57
import junit.framework.Test;
58
import org.openide.actions.EditAction;
59
import org.openide.nodes.Node;
60
import org.openide.util.Utilities;
51
61
52
/** Check what can be done when registering loaders in layer.
62
/** Check what can be done when registering loaders in layer.
53
 * @author Jaroslav Tulach
63
 * @author Jaroslav Tulach
Lines 93-98 public class DataLoaderInLayerTest exten Link Here
93
            }
103
            }
94
        }
104
        }
95
    }
105
    }
106
    private static <F extends DataObject.Factory> void addRemove(String mime, F factory, boolean add) throws IOException {
107
        String res = "Loaders/" + mime + "/Factories/" + factory.getClass().getSimpleName().replace('.', '-') + ".instance";
108
        FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
109
        if (add) {
110
            FileObject fo = FileUtil.createData(root, res);
111
            fo.setAttribute("instanceCreate", factory);
112
            assertSame("No serialization, just memory fs is used", factory, fo.getAttribute("instanceCreate"));
113
        } else {
114
            FileObject fo = root.getFileObject(res);
115
            if (fo != null) {
116
                fo.delete();
117
            }
118
        }
119
    }
96
    
120
    
97
    public void testSimpleGetChildren() throws Exception {
121
    public void testSimpleGetChildren() throws Exception {
98
        DataLoader l = DataLoader.getLoader(SimpleUniFileLoader.class);
122
        DataLoader l = DataLoader.getLoader(SimpleUniFileLoader.class);
Lines 122-127 public class DataLoaderInLayerTest exten Link Here
122
            assertEquals(SimpleDataObject.class, dob.getClass());
146
            assertEquals(SimpleDataObject.class, dob.getClass());
123
        } finally {
147
        } finally {
124
            addRemove("text/plain", SimpleFactory.class, false);
148
            addRemove("text/plain", SimpleFactory.class, false);
149
        }
150
    }
151
152
    public void testFactoryInstanceRegistrationWorksAsWell() throws Exception {
153
        URL u = DataLoaderInLayerTest.class.getResource("/org/openide/loaders/saveAll.gif");
154
        Image img = Toolkit.getDefaultToolkit().createImage(u);
155
        
156
        DataObject.Factory f = DataLoaderPool.factory(SimpleDataObject.class, "text/simplefactory", img);
157
        
158
        addRemove("text/plain", f, true);
159
        try {
160
            FileSystem lfs = createFS("folderF/file.simple");
161
            FileObject fo = lfs.findResource("folderF");
162
            DataFolder df = DataFolder.findFolder(fo);
163
            DataObject[] arr = df.getChildren();
164
            assertEquals("One object", 1, arr.length);
165
            DataObject dob = arr[0];
166
            assertEquals(SimpleDataObject.class, dob.getClass());
167
            
168
            FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
169
            FileObject edit = FileUtil.createData(root, "/Loaders/text/simplefactory/Actions/org-openide-actions-EditAction.instance");
170
            
171
            Node node = dob.getNodeDelegate();
172
            Action[] actions = node.getActions(true);
173
            assertEquals("One action is present: " + Arrays.asList(actions), 1, actions.length);
174
            assertEquals("It is the edit one", EditAction.class, actions[0].getClass());
175
            
176
            assertSame("Icon is propagated for open", img, node.getOpenedIcon(0));
177
            assertSame("Icon is propagated", img, node.getIcon(0));
178
            
179
            Reference<DataFolder> ref = new WeakReference<DataFolder>(df);
180
            df = null;
181
            assertGC("Folder can go away", ref);
182
            
183
            df = DataFolder.findFolder(fo);
184
            arr = df.getChildren();
185
            assertEquals("One object", 1, arr.length);
186
            assertEquals("Object is the same", dob, arr[0]);
187
        } finally {
188
            addRemove("text/plain", f, false);
189
        }
190
    }
191
    
192
    public void testFactoryInstanceRegistrationWorksAsWellNowFromLayer() throws Exception {
193
        URL u = DataLoaderInLayerTest.class.getResource("/org/openide/loaders/saveAll.gif");
194
        FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
195
        FileObject instance = FileUtil.createData(root, "TestLoaders/text/L.instance");
196
        instance.setAttribute("dataObjectClass", SimpleDataObject.class.getName());
197
        instance.setAttribute("mimeType", "text/simplefactory");
198
        instance.setAttribute("SystemFileSystem.icon", u);
199
        
200
        
201
        Image img = Utilities.loadImage("org/openide/loaders/saveAll.gif");
202
        
203
        DataObject.Factory f = DataLoaderPool.factory(instance);
204
        
205
        addRemove("text/plain", f, true);
206
        try {
207
            FileSystem lfs = createFS("folderQ/file.simple");
208
            FileObject fo = lfs.findResource("folderQ");
209
            DataFolder df = DataFolder.findFolder(fo);
210
            DataObject[] arr = df.getChildren();
211
            assertEquals("One object", 1, arr.length);
212
            DataObject dob = arr[0];
213
            assertEquals(SimpleDataObject.class, dob.getClass());
214
            
215
            FileObject edit = FileUtil.createData(root, "/Loaders/text/simplefactory/Actions/org-openide-actions-EditAction.instance");
216
            
217
            Node node = dob.getNodeDelegate();
218
            Action[] actions = node.getActions(true);
219
            assertEquals("One action is present: " + Arrays.asList(actions), 1, actions.length);
220
            assertEquals("It is the edit one", EditAction.class, actions[0].getClass());
221
            
222
            assertImage("Icon is propagated for open", img, node.getOpenedIcon(0));
223
            assertImage("Icon is propagated", img, node.getIcon(0));
224
            
225
            Reference<DataFolder> ref = new WeakReference<DataFolder>(df);
226
            df = null;
227
            assertGC("Folder can go away", ref);
228
            
229
            df = DataFolder.findFolder(fo);
230
            arr = df.getChildren();
231
            assertEquals("One object", 1, arr.length);
232
            assertEquals("Object is the same", dob, arr[0]);
233
        } finally {
234
            addRemove("text/plain", f, false);
125
        }
235
        }
126
    }
236
    }
127
237
Lines 311-315 public class DataLoaderInLayerTest exten Link Here
311
            supp.remove (l);
421
            supp.remove (l);
312
        }        
422
        }        
313
    }
423
    }
314
    
424
425
    private static void assertImage(String msg, Image img1, Image img2) {
426
        ImageObserver obs = new ImageObserver() {
427
            public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
428
                fail("Already updated, hopefully");
429
                return true;
430
            }
431
        };
432
        
433
        int h, w;
434
        assertEquals("Width: " + msg, w = img1.getWidth(obs), img2.getWidth(obs));
435
        assertEquals("Height: " + msg, h = img1.getHeight(obs), img2.getHeight(obs));
436
        
437
        
438
        for (int i = 0; i < w; i++) {
439
            for (int j = 0; j < h; j++) {
440
                //assertEquals("Pixel " + i + ", " + j + " same: " + msg, img1.get)
441
            }
442
        }
443
        
444
    }
315
}
445
}

Return to bug 91665