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 138846
Collapse All | Expand All

(-)a/o.n.core/test/unit/src/org/netbeans/core/filesystems/ArchiveURLMapperTest.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.core.startup.layers;
43
43
44
import java.io.File;
44
import java.io.File;
45
import java.io.FileOutputStream;
45
import java.io.FileOutputStream;
(-)a/o.n.core/test/unit/src/org/netbeans/core/filesystems/NbinstURLMapperTest.java (-6 / +3 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.core.startup.layers;
43
43
44
import java.io.BufferedReader;
44
import java.io.BufferedReader;
45
import java.io.File;
45
import java.io.File;
Lines 51-61 Link Here
51
import java.net.URL;
51
import java.net.URL;
52
import java.net.URLConnection;
52
import java.net.URLConnection;
53
import java.util.StringTokenizer;
53
import java.util.StringTokenizer;
54
import org.netbeans.core.startup.layers.NbinstURLMapper;
55
import org.netbeans.core.startup.layers.NbinstURLStreamHandlerFactory;
56
import org.netbeans.junit.MockServices;
54
import org.netbeans.junit.MockServices;
57
import org.netbeans.junit.NbTestCase;
55
import org.netbeans.junit.NbTestCase;
58
import org.netbeans.modules.masterfs.MasterURLMapper;
59
import org.openide.filesystems.FileObject;
56
import org.openide.filesystems.FileObject;
60
import org.openide.filesystems.FileUtil;
57
import org.openide.filesystems.FileUtil;
61
import org.openide.filesystems.URLMapper;
58
import org.openide.filesystems.URLMapper;
Lines 74-87 Link Here
74
        super (testName);
71
        super (testName);
75
    }
72
    }
76
73
74
    @Override
77
    protected void setUp() throws Exception {
75
    protected void setUp() throws Exception {
78
        super.setUp();
76
        super.setUp();
79
        
77
        
80
        MockServices.setServices(
78
        MockServices.setServices(
81
                TestInstalledFileLocator.class,
79
                TestInstalledFileLocator.class,
82
                NbinstURLStreamHandlerFactory.class,
80
                NbinstURLStreamHandlerFactory.class,
83
                NbinstURLMapper.class,
81
                NbinstURLMapper.class);
84
                MasterURLMapper.class);
85
82
86
        org.netbeans.core.startup.Main.initializeURLFactory ();
83
        org.netbeans.core.startup.Main.initializeURLFactory ();
87
        
84
        
(-)a/core.ui/nbproject/project.xml (-1 / +1 lines)
Lines 118-124 Link Here
118
                    <build-prerequisite/>
118
                    <build-prerequisite/>
119
                    <compile-dependency/>
119
                    <compile-dependency/>
120
                    <run-dependency>
120
                    <run-dependency>
121
                        <specification-version>7.7</specification-version>
121
                        <implementation-version/>
122
                    </run-dependency>
122
                    </run-dependency>
123
                </dependency>
123
                </dependency>
124
                <dependency>
124
                <dependency>
(-)a/core.ui/src/org/netbeans/core/ui/options/filetypes/FileAssociationsModel.java (-15 / +25 lines)
Lines 50-65 Link Here
50
import java.util.TreeSet;
50
import java.util.TreeSet;
51
import java.util.logging.Level;
51
import java.util.logging.Level;
52
import java.util.logging.Logger;
52
import java.util.logging.Logger;
53
import org.netbeans.core.LoaderPoolNode;
53
import org.netbeans.modules.openide.filesystems.declmime.MIMEResolverImpl;
54
import org.openide.filesystems.FileChangeAdapter;
55
import org.openide.filesystems.FileChangeListener;
56
import org.openide.filesystems.FileEvent;
54
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileRenameEvent;
55
import org.openide.filesystems.FileSystem;
59
import org.openide.filesystems.FileSystem;
56
import org.openide.filesystems.FileUtil;
60
import org.openide.filesystems.FileUtil;
57
import org.openide.filesystems.MIMEResolver;
58
import org.openide.filesystems.Repository;
61
import org.openide.filesystems.Repository;
59
import org.openide.loaders.DataLoader;
62
import org.openide.loaders.DataLoader;
60
import org.openide.util.Lookup;
61
import org.openide.util.LookupEvent;
62
import org.openide.util.LookupListener;
63
import org.openide.util.lookup.Lookups;
63
import org.openide.util.lookup.Lookups;
64
import org.openide.xml.XMLUtil;
64
import org.openide.xml.XMLUtil;
65
import org.w3c.dom.Document;
65
import org.w3c.dom.Document;
Lines 87-99 Link Here
87
    /** Maps MIME type to MimeItem object which holds display name. */
87
    /** Maps MIME type to MimeItem object which holds display name. */
88
    private HashMap<String, MimeItem> mimeToItem = new HashMap<String, MimeItem>();
88
    private HashMap<String, MimeItem> mimeToItem = new HashMap<String, MimeItem>();
89
    private boolean initialized = false;
89
    private boolean initialized = false;
90
    private LookupListener lookupListener = new LookupListenerImpl();
90
    private final FileChangeListener mimeResolversListener = new FileChangeAdapter() {
91
        public @Override void fileDeleted(FileEvent fe) {
92
            initialized = false;
93
        }
94
        public @Override void fileRenamed(FileRenameEvent fe) {
95
            initialized = false;
96
        }
97
        public @Override void fileDataCreated(FileEvent fe) {
98
            initialized = false;
99
        }
100
        public @Override void fileChanged(FileEvent fe) {
101
            initialized = false;
102
        }
103
    };
91
    private FileObject userDefinedResolverFO;
104
    private FileObject userDefinedResolverFO;
92
105
93
    /** Creates new model. */
106
    /** Creates new model. */
94
    FileAssociationsModel() {
107
    FileAssociationsModel() {
95
        Lookup lookup = Lookups.forPath(MIME_RESOLVERS_PATH);
108
        FileObject resolvers = Repository.getDefault().getDefaultFileSystem().findResource(MIME_RESOLVERS_PATH);
96
        lookup.lookupResult(MIMEResolver.class).addLookupListener(lookupListener);
109
        if (resolvers != null) {
110
            resolvers.addFileChangeListener(FileUtil.weakFileChangeListener(mimeResolversListener, resolvers));
111
        }
97
    }
112
    }
98
113
99
    /** Returns true if model includes given extension. */
114
    /** Returns true if model includes given extension. */
Lines 303-309 Link Here
303
            if (userDefined) {
318
            if (userDefined) {
304
                userDefinedResolverFO = mimeResolverFO;
319
                userDefinedResolverFO = mimeResolverFO;
305
            }
320
            }
306
            ArrayList<String[]> extAndMimePairs = LoaderPoolNode.getExtensionsAndMIMETypes(mimeResolverFO);
321
            assert mimeResolverFO.getPath().startsWith("Services/MIMEResolver");  //NOI18N
322
            ArrayList<String[]> extAndMimePairs = MIMEResolverImpl.getExtensionsAndMIMETypes(mimeResolverFO);
307
            Iterator<String[]> iter = extAndMimePairs.iterator();
323
            Iterator<String[]> iter = extAndMimePairs.iterator();
308
            while (iter.hasNext()) {
324
            while (iter.hasNext()) {
309
                String[] pair = iter.next();
325
                String[] pair = iter.next();
Lines 328-339 Link Here
328
        }
344
        }
329
        LOGGER.fine("extensionToMimeSystem=" + extensionToMimeSystem);  //NOI18N
345
        LOGGER.fine("extensionToMimeSystem=" + extensionToMimeSystem);  //NOI18N
330
        LOGGER.fine("extensionToMimeUser=" + extensionToMimeUser);  //NOI18N
346
        LOGGER.fine("extensionToMimeUser=" + extensionToMimeUser);  //NOI18N
331
    }
332
    
333
    private class LookupListenerImpl implements LookupListener {
334
        public void resultChanged(LookupEvent ev) {
335
            initialized = false;
336
        }
337
    }
347
    }
338
    
348
    
339
    /** To store MIME type and its loader display name. It is used in combo box. */
349
    /** To store MIME type and its loader display name. It is used in combo box. */
(-)a/o.n.core/src/org/netbeans/core/Bundle.properties (-2 lines)
Lines 45-52 Link Here
45
        This module provides the central infrastructure \
45
        This module provides the central infrastructure \
46
        that lets NetBeans-based applications run. \
46
        that lets NetBeans-based applications run. \
47
        It cannot be disabled.
47
        It cannot be disabled.
48
49
Services/MIMEResolver=File Types
50
48
51
#DataSystem
49
#DataSystem
52
dataSystemName=All Files
50
dataSystemName=All Files
(-)a/o.n.core/src/org/netbeans/core/LoaderPoolNode.java (-12 / +1 lines)
Lines 64-70 Link Here
64
import javax.swing.Action;
64
import javax.swing.Action;
65
import javax.swing.event.ChangeEvent;
65
import javax.swing.event.ChangeEvent;
66
import javax.swing.event.ChangeListener;
66
import javax.swing.event.ChangeListener;
67
import org.netbeans.core.filesystems.MIMEResolverImpl;
68
import org.netbeans.core.startup.ManifestSection;
67
import org.netbeans.core.startup.ManifestSection;
69
import org.openide.actions.MoveDownAction;
68
import org.openide.actions.MoveDownAction;
70
import org.openide.actions.MoveUpAction;
69
import org.openide.actions.MoveUpAction;
Lines 90-95 Link Here
90
import org.openide.util.LookupEvent;
89
import org.openide.util.LookupEvent;
91
import org.openide.util.LookupListener;
90
import org.openide.util.LookupListener;
92
import org.openide.util.NbBundle;
91
import org.openide.util.NbBundle;
92
import org.openide.util.NotImplementedException;
93
import org.openide.util.RequestProcessor;
93
import org.openide.util.RequestProcessor;
94
import org.openide.util.TopologicalSortException;
94
import org.openide.util.TopologicalSortException;
95
import org.openide.util.Utilities;
95
import org.openide.util.Utilities;
Lines 739-755 Link Here
739
    }
739
    }
740
    private static NbLoaderPool nbLoaderPool = null;
740
    private static NbLoaderPool nbLoaderPool = null;
741
741
742
    /** Returns list of extension and MIME type pairs for given MIMEResolver
743
     * FileObject. The list can contain duplicates and also [null, MIME] pairs.
744
     * @param fo MIMEResolver FileObject
745
     * @return list of extension and MIME type pairs. The list can contain 
746
     * duplicates and also [null, MIME] pairs.
747
     * @since 3.9
748
     */
749
    public static ArrayList<String[]> getExtensionsAndMIMETypes(FileObject fo) {
750
        return MIMEResolverImpl.getExtensionsAndMIMETypes(fo);
751
    }
752
753
    /***** Inner classes **************/
742
    /***** Inner classes **************/
754
743
755
    /** Node representing one loader in Loader Pool */
744
    /** Node representing one loader in Loader Pool */
(-)a/o.n.core/src/org/netbeans/core/filesystems/XMLEnvironmentProvider.java (-123 lines)
Lines 1-123 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
42
package org.netbeans.core.filesystems;
43
44
import java.io.*;
45
import java.util.*;
46
47
import org.xml.sax.*;
48
import org.xml.sax.helpers.*;
49
50
import org.openide.cookies.InstanceCookie;
51
import org.openide.loaders.*;
52
import org.openide.filesystems.*;
53
import org.openide.util.*;
54
import org.openide.util.lookup.*;
55
import org.openide.xml.*;
56
import org.openide.*;
57
58
/**
59
 * Default implementation providing Environment for XMLDataObject according to its
60
 * public ID.
61
 *
62
 * <p>
63
 * Subclass instance of this must be registered as <tt>FileEntityResolver</tt>
64
 * dictates and must implement <tt>Environment.Provider</tt> interface.
65
 *
66
 * <p>
67
 * It forever caches provided environment!
68
 *
69
 * @see     org.netbeans.core.xml.FileEntityResolver
70
 * @author  Petr Kuzel
71
 * @version 
72
 */
73
class XMLEnvironmentProvider extends SharedClassObject {
74
75
    private static final long serialVersionUID = 18947L;
76
    
77
    private static transient Map<FileObject, Lookup> envs = new HashMap<FileObject, Lookup>(11); // 11 expected number of modules using this
78
    
79
    // Environment.Provider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80
    
81
    /** Returns a lookup that represents environment.
82
     * @return the lookup
83
     */
84
    public final Lookup getEnvironment(DataObject obj){
85
        
86
        // the obj check is done by core FileEntityResolver that calls us
87
        
88
        // we want to create just one instance per FileObject
89
90
        FileObject file = obj.getPrimaryFile();
91
        Lookup lookup = envs.get(file);
92
        if (lookup == null) {
93
            lookup = createLookup(obj);
94
            envs.put(file, lookup);
95
        }
96
        return lookup;
97
        
98
    }
99
    
100
    /**
101
     * It is called exactly once per DataObject.
102
     *
103
     * @return content of assigned Lookup
104
     */
105
    protected InstanceContent createInstanceContent(DataObject obj) {
106
        return new InstanceContent();
107
    }
108
    
109
    /**
110
     * It is called exactly once per DataObject.
111
     *
112
     * @return Lookup containing <tt>createInstanceContent()</tt>
113
     */
114
    protected Lookup createLookup(DataObject obj) {
115
        InstanceContent ic = createInstanceContent(obj);
116
        Lookup lookup = new AbstractLookup(ic);
117
        if (lookup.lookup(InstanceCookie.class) == null) {
118
            Exceptions.printStackTrace(new IllegalStateException());  // instance cookie required
119
        }
120
        return lookup;
121
    }
122
            
123
}
(-)a/o.n.core/src/org/netbeans/core/resources/mf-layer.xml (-14 / +2 lines)
Lines 53-64 Link Here
53
            </file>
53
            </file>
54
        </folder>
54
        </folder>
55
    
55
    
56
        <folder name="MIMEResolver">
57
            <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.core.Bundle" />
58
            <attr name="SystemFileSystem.icon" urlvalue="nbresloc:/org/netbeans/core/resources/mime.gif" />        
59
            <attr name="helpID" stringvalue="org.netbeans.core.filesystems.MIMEResolverImpl"/>
60
        </folder>
61
62
        <folder name="Hidden">
56
        <folder name="Hidden">
63
            <attr name="hidden" boolvalue="true" />
57
            <attr name="hidden" boolvalue="true" />
64
            <file name="HtmlBrowserFactoryEditorForGeneralOptionsPanel.instance">
58
            <file name="HtmlBrowserFactoryEditorForGeneralOptionsPanel.instance">
Lines 109-119 Link Here
109
                </file>
103
                </file>
110
104
111
                <!-- Declarative MIME resolver -->
105
                <!-- Declarative MIME resolver -->
112
                <file name="DTD_MIME_Resolver_1_0" url="nbres:/org/netbeans/core/filesystems/resolver.dtd">
106
                <file name="DTD_MIME_Resolver_1_0" url="nbres:/org/netbeans/modules/openide/filesystems/declmime/resolver.dtd">
113
                    <attr name="hint.originalPublicID" stringvalue="-//NetBeans//DTD MIME Resolver 1.0//EN"/>
107
                    <attr name="hint.originalPublicID" stringvalue="-//NetBeans//DTD MIME Resolver 1.0//EN"/>
114
                </file>
108
                </file>
115
109
116
                <file name="DTD_MIME_Resolver_XML_Rules_1_0" url="nbres:/org/netbeans/core/filesystems/xml-rules.dtd">
110
                <file name="DTD_MIME_Resolver_XML_Rules_1_0" url="nbres:/org/netbeans/modules/openide/filesystems/declmime/xml-rules.dtd">
117
                    <attr name="hint.originalPublicID" stringvalue="-//NetBeans//DTD MIME Resolver XML Rules 1.0//EN"/>
111
                    <attr name="hint.originalPublicID" stringvalue="-//NetBeans//DTD MIME Resolver XML Rules 1.0//EN"/>
118
                </file>            
112
                </file>            
119
113
Lines 129-140 Link Here
129
                    <attr name="instanceClass" stringvalue="org.openide.loaders.XMLDataObject$Processor"/>
123
                    <attr name="instanceClass" stringvalue="org.openide.loaders.XMLDataObject$Processor"/>
130
                    <attr name="instanceCreate" newvalue="org.netbeans.core.xml.EntityCatalogImpl$RegistrationProcessor" />
124
                    <attr name="instanceCreate" newvalue="org.netbeans.core.xml.EntityCatalogImpl$RegistrationProcessor" />
131
                </file>
125
                </file>
132
133
                <!-- Environment.Provider for declarative MIME resolver XML documents. -->
134
                <file name="DTD_MIME_Resolver_1_0.instance">
135
                    <attr name="instanceClass" stringvalue="org.openide.loaders.Environment$Provider"/>
136
                    <attr name="instanceCreate" newvalue="org.netbeans.core.filesystems.MIMEResolverImpl"/>
137
                </file>
138
            </folder>
126
            </folder>
139
        </folder>
127
        </folder>
140
    </folder>
128
    </folder>
(-)a/o.n.core/test/unit/src/org/netbeans/core/filesystems/FileEntityResolverTest.java (-4 / +3 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.core;
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import java.io.OutputStream;
45
import java.io.OutputStream;
Lines 50-56 Link Here
50
import java.util.jar.Attributes;
50
import java.util.jar.Attributes;
51
import javax.swing.event.ChangeEvent;
51
import javax.swing.event.ChangeEvent;
52
import javax.swing.event.ChangeListener;
52
import javax.swing.event.ChangeListener;
53
import org.netbeans.core.LoaderPoolNode;
54
import org.netbeans.core.startup.ManifestSection;
53
import org.netbeans.core.startup.ManifestSection;
55
import org.openide.ErrorManager;
54
import org.openide.ErrorManager;
56
import org.openide.filesystems.FileObject;
55
import org.openide.filesystems.FileObject;
Lines 71-77 Link Here
71
 *
70
 *
72
 * @author Jaroslav Tulach
71
 * @author Jaroslav Tulach
73
 */
72
 */
74
public class FileEntityResolverTest extends org.netbeans.core.LoggingTestCaseHid 
73
public class LoaderPoolNodeResolverChangeTest extends org.netbeans.core.LoggingTestCaseHid 
75
implements LookupListener, ChangeListener {
74
implements LookupListener, ChangeListener {
76
    private FileObject fo;
75
    private FileObject fo;
77
    private Lenka loader;
76
    private Lenka loader;
Lines 81-87 Link Here
81
    private int poolChange;
80
    private int poolChange;
82
    private static ErrorManager err;
81
    private static ErrorManager err;
83
    
82
    
84
    public FileEntityResolverTest(String testName) {
83
    public LoaderPoolNodeResolverChangeTest(String testName) {
85
        super(testName);
84
        super(testName);
86
    }
85
    }
87
86
(-)a/openide.filesystems/manifest.mf (-1 / +1 lines)
Lines 1-5 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.openide.filesystems
2
OpenIDE-Module: org.openide.filesystems
3
OpenIDE-Module-Specification-Version: 7.10
3
OpenIDE-Module-Implementation-Version: 1
4
OpenIDE-Module-Localizing-Bundle: org/openide/filesystems/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/openide/filesystems/Bundle.properties
5
5
(-)a/openide.filesystems/nbproject/project.properties (+1 lines)
Lines 43-45 Link Here
43
javadoc.main.page=org/openide/filesystems/doc-files/api.html
43
javadoc.main.page=org/openide/filesystems/doc-files/api.html
44
javadoc.arch=${basedir}/arch.xml
44
javadoc.arch=${basedir}/arch.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
46
spec.version.base=7.10.0
(-)a/o.n.core/src/org/netbeans/core/filesystems/DefaultParser.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import java.io.*;
44
import java.io.*;
45
import java.util.logging.Level;
45
import java.util.logging.Level;
(-)a/o.n.core/src/org/netbeans/core/filesystems/FileObjectFilter.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import org.openide.filesystems.*;
44
import org.openide.filesystems.*;
45
45
(-)a/o.n.core/src/org/netbeans/core/filesystems/MIMEComponent.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import org.xml.sax.ContentHandler;
44
import org.xml.sax.ContentHandler;
45
45
(-)a/o.n.core/src/org/netbeans/core/filesystems/MIMEResolverImpl.java (-112 / +61 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import java.io.FileNotFoundException;
44
import java.io.FileNotFoundException;
45
import java.io.IOException;
45
import java.io.IOException;
Lines 47-60 Link Here
47
import java.util.ArrayList;
47
import java.util.ArrayList;
48
import java.util.logging.Level;
48
import java.util.logging.Level;
49
import java.util.logging.Logger;
49
import java.util.logging.Logger;
50
import org.openide.cookies.InstanceCookie;
51
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
52
import org.openide.filesystems.FileUtil;
51
import org.openide.filesystems.FileUtil;
53
import org.openide.filesystems.MIMEResolver;
52
import org.openide.filesystems.MIMEResolver;
54
import org.openide.loaders.DataObject;
55
import org.openide.loaders.Environment;
56
import org.openide.util.Utilities;
53
import org.openide.util.Utilities;
57
import org.openide.util.lookup.InstanceContent;
58
import org.openide.xml.XMLUtil;
54
import org.openide.xml.XMLUtil;
59
import org.xml.sax.Attributes;
55
import org.xml.sax.Attributes;
60
import org.xml.sax.SAXException;
56
import org.xml.sax.SAXException;
Lines 63-82 Link Here
63
 * MIMEResolver implementation driven by an XML document instance
59
 * MIMEResolver implementation driven by an XML document instance
64
 * following PUBLIC "-//NetBeans//DTD MIME Resolver 1.0//EN".
60
 * following PUBLIC "-//NetBeans//DTD MIME Resolver 1.0//EN".
65
 *
61
 *
66
 * <p>
67
 * 1. It provides Environment for XMLDataObjects with above public ID.
68
 * <p>
69
 * 2. Provided environment returns (InstanceCookie) Impl instance.
70
 * <p>
71
 * 3. [Instance]Lookup return that Impl instance.
72
 * <p>
73
 * 4. MIMEResolver's findMIMEType() parses description file and applies checks on passed files.
74
 * <p>
75
 * <b>Note:</b> It is public to be accessible by XML layer.
76
 *
77
 * @author  Petr Kuzel
62
 * @author  Petr Kuzel
78
 */
63
 */
79
public final class MIMEResolverImpl extends XMLEnvironmentProvider implements Environment.Provider {
64
public final class MIMEResolverImpl extends MIMEResolver {
80
65
81
    private static final long serialVersionUID = 18975L;
66
    private static final long serialVersionUID = 18975L;
82
    
67
    
Lines 86-110 Link Here
86
    private static final boolean CASE_INSENSITIVE =
71
    private static final boolean CASE_INSENSITIVE =
87
        Utilities.isWindows() || Utilities.getOperatingSystem() == Utilities.OS_VMS;
72
        Utilities.isWindows() || Utilities.getOperatingSystem() == Utilities.OS_VMS;
88
    
73
    
89
    // DefaultEnvironmentProvider~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90
    
91
    protected InstanceContent createInstanceContent(DataObject obj) {
92
        FileObject fo = obj.getPrimaryFile();
93
        InstanceContent ic = new InstanceContent();
94
        ic.add(new Impl(fo));
95
        return ic;
96
    }
97
    
98
    /** Returns list of extension and MIME type pairs for given MIMEResolver
99
     * FileObject. The list can contain duplicates and also [null, MIME] pairs.
100
     * @param fo MIMEResolver FileObject
101
     * @return list of extension and MIME type pairs. The list can contain 
102
     * duplicates and also [null, MIME] pairs.
103
     */
104
    public static ArrayList<String[]> getExtensionsAndMIMETypes(FileObject fo) {
74
    public static ArrayList<String[]> getExtensionsAndMIMETypes(FileObject fo) {
105
        assert fo.getPath().startsWith("Services/MIMEResolver");  //NOI18N
106
        ArrayList<String[]> result = new ArrayList<String[]>();
75
        ArrayList<String[]> result = new ArrayList<String[]>();
107
        Impl impl = new Impl(fo);
76
        MIMEResolverImpl impl = new MIMEResolverImpl(fo);
108
        impl.parseDesc();
77
        impl.parseDesc();
109
        FileElement[] elements = impl.smell;
78
        FileElement[] elements = impl.smell;
110
        if(elements != null) {
79
        if(elements != null) {
Lines 124-223 Link Here
124
        return result;
93
        return result;
125
    }
94
    }
126
    
95
    
127
    // MIMEResolver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96
    // This file object describes rules that drive ths instance
97
    private final FileObject data;
128
98
129
    //
99
    // Resolvers in reverse order
130
    // It implements InstanceCookie because it is added to environment of XML document.
100
    private FileElement[] smell = null;
131
    // The cookie return itself i.e. MIMEResolver to be searchable by Lookup.
132
    //
133
    static class Impl extends MIMEResolver implements InstanceCookie {
134
        // This file object describes rules that drive ths instance
135
        private final FileObject data;
136
101
137
        // Resolvers in reverse order
102
    private short state = DescParser.INIT;
138
        private FileElement[] smell = null;
103
139
                
104
    public MIMEResolverImpl(FileObject obj) {
140
        private short state = DescParser.INIT;
105
        if (ERR.isLoggable(Level.FINE)) {
141
        
106
            ERR.fine("MIMEResolverImpl.<init>(" + obj + ")");  // NOI18N
142
        Impl(FileObject obj) {
143
            if (ERR.isLoggable(Level.FINE)) ERR.fine("MIMEResolverImpl.Impl.<init>(" + obj + ")");  // NOI18N
144
            data = obj;
145
        }
107
        }
146
        
108
        data = obj;
147
        /**
109
    }
148
         * Resolves FileObject and returns recognized MIME type
149
         * @param fo is FileObject which should be resolved
150
         * @return  recognized MIME type or null if not recognized
151
         */
152
        public String findMIMEType(FileObject fo) {
153
110
154
            synchronized (this) {  // lazy init
111
    /**
112
     * Resolves FileObject and returns recognized MIME type
113
     * @param fo is FileObject which should be resolved
114
     * @return  recognized MIME type or null if not recognized
115
     */
116
    public String findMIMEType(FileObject fo) {
155
117
156
                if (state == DescParser.INIT) {
118
        synchronized (this) {  // lazy init
157
                    state = parseDesc();
119
158
                }
120
            if (state == DescParser.INIT) {
159
                
121
                state = parseDesc();
160
                if (state == DescParser.ERROR) {                    
161
                    return null;
162
                }                
163
            }
122
            }
164
123
165
            // smell is filled in reverse order
124
            if (state == DescParser.ERROR) {
166
            
125
                return null;
167
            for (int i = smell.length-1; i>=0; i--) {
168
                String s = smell[i].resolve(fo);
169
                if (s != null) {
170
                    if (ERR.isLoggable(Level.FINE)) ERR.fine("MIMEResolverImpl.findMIMEType(" + fo + ")=" + s);  // NOI18N
171
                    return s;
172
                }
173
            }
126
            }
174
            
175
            return null;
176
        }
127
        }
177
128
178
        // description document is parsed in the same thread
129
        // smell is filled in reverse order
179
        private short parseDesc() {
130
180
            smell = new FileElement[0];
131
        for (int i = smell.length - 1; i >= 0; i--) {
181
            DescParser parser = new DescParser(data);
132
            String s = smell[i].resolve(fo);
182
            parser.parse();
133
            if (s != null) {
183
            smell = (parser.template != null) ? parser.template : smell;
134
                if (ERR.isLoggable(Level.FINE)) {
184
            if (ERR.isLoggable(Level.FINE)) {
135
                    ERR.fine("MIMEResolverImpl.findMIMEType(" + fo + ")=" + s);  // NOI18N
185
                if (parser.state == DescParser.ERROR) {
186
                    ERR.fine("MIMEResolverImpl.Impl parsing error!");
187
                } else {
188
                    StringBuffer buf = new StringBuffer();
189
                    buf.append("Parse: ");
190
                    for (int i = 0; i<smell.length; i++)
191
                        buf.append('\n').append(smell[i]);
192
                    ERR.fine(buf.toString());
193
                }
136
                }
137
                return s;
194
            }
138
            }
195
            return parser.state;
196
        }
197
        
198
        // InstanceCookie ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199
200
        public Object instanceCreate() {
201
            return this;
202
        }    
203
204
        public Class instanceClass() {
205
            return this.getClass();
206
        }    
207
208
        public String instanceName() {
209
            return this.getClass().getName();
210
        }
139
        }
211
140
212
        /** For debug purposes. */
141
        return null;
213
        public String toString() {
214
            return "MIMEResolverImpl.Impl[" + data + ", " + smell + "]";  // NOI18N
215
        }
216
217
        
218
    }
142
    }
219
143
220
    
144
    // description document is parsed in the same thread
145
    private short parseDesc() {
146
        smell = new FileElement[0];
147
        DescParser parser = new DescParser(data);
148
        parser.parse();
149
        smell = (parser.template != null) ? parser.template : smell;
150
        if (ERR.isLoggable(Level.FINE)) {
151
            if (parser.state == DescParser.ERROR) {
152
                ERR.fine("MIMEResolverImpl parsing error!");
153
            } else {
154
                StringBuffer buf = new StringBuffer();
155
                buf.append("Parse: ");
156
                for (int i = 0; i < smell.length; i++) {
157
                    buf.append('\n').append(smell[i]);
158
                }
159
                ERR.fine(buf.toString());
160
            }
161
        }
162
        return parser.state;
163
    }
164
165
    /** For debug purposes. */
166
    public String toString() {
167
        return "MIMEResolverImpl[" + data + ", " + smell + "]";  // NOI18N
168
    }
169
221
    // XML -> memory representation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170
    // XML -> memory representation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
222
171
223
    /**
172
    /**
(-)a/o.n.core/src/org/netbeans/core/filesystems/Util.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import org.openide.util.Utilities;
44
import org.openide.util.Utilities;
45
45
(-)a/o.n.core/src/org/netbeans/core/filesystems/XMLMIMEComponent.java (-2 / +2 lines)
Lines 39-45 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import java.lang.ref.WeakReference;
44
import java.lang.ref.WeakReference;
45
import java.util.logging.Level;
45
import java.util.logging.Level;
Lines 337-343 Link Here
337
            
337
            
338
            // it may be caused by wrong user XML documents, notify only in debug mode
338
            // it may be caused by wrong user XML documents, notify only in debug mode
339
            // also see #16484 if the error message makes no sense
339
            // also see #16484 if the error message makes no sense
340
            Logger emgr = Logger.getLogger("org.netbeans.core.filesystems.XMLMIMEComponent"); // NOI18N
340
            Logger emgr = Logger.getLogger(XMLMIMEComponent.class.getName());
341
            if (emgr.isLoggable(Level.FINE)) {
341
            if (emgr.isLoggable(Level.FINE)) {
342
                emgr.fine("[while parsing " + fo + "] " + exception.getSystemId() + ":" + exception.getLineNumber() + ":" + exception.getColumnNumber() + ": " + exception.getMessage()); // NOI18N
342
                emgr.fine("[while parsing " + fo + "] " + exception.getSystemId() + ":" + exception.getLineNumber() + ":" + exception.getColumnNumber() + ": " + exception.getMessage()); // NOI18N
343
            }
343
            }
(-)a/openide.filesystems/src/org/openide/filesystems/MIMESupport.java (-2 / +18 lines)
Lines 47-56 Link Here
47
import java.io.OutputStream;
47
import java.io.OutputStream;
48
import java.lang.ref.Reference;
48
import java.lang.ref.Reference;
49
import java.lang.ref.WeakReference;
49
import java.lang.ref.WeakReference;
50
import java.util.ArrayList;
51
import java.util.Arrays;
50
import java.util.Enumeration;
52
import java.util.Enumeration;
51
import java.util.HashSet;
53
import java.util.HashSet;
54
import java.util.List;
52
import java.util.Set;
55
import java.util.Set;
53
import java.util.logging.Logger;
56
import java.util.logging.Logger;
57
import org.netbeans.modules.openide.filesystems.declmime.MIMEResolverImpl;
54
import org.openide.util.Lookup;
58
import org.openide.util.Lookup;
55
import org.openide.util.LookupEvent;
59
import org.openide.util.LookupEvent;
56
import org.openide.util.LookupListener;
60
import org.openide.util.LookupListener;
Lines 194-201 Link Here
194
            }
198
            }
195
199
196
            ERR.fine("Computing resolvers"); // NOI18N
200
            ERR.fine("Computing resolvers"); // NOI18N
197
            
201
198
            MIMEResolver[] toRet = result.allInstances().toArray(new MIMEResolver[0]);
202
            List<MIMEResolver> all = new ArrayList<MIMEResolver>(result.allInstances());
203
204
            FileObject declarativeFolder = Repository.getDefault().getDefaultFileSystem().findResource("Services/MIMEResolver"); // NOI18N
205
            if (declarativeFolder != null) {
206
                for (FileObject f : Ordering.getOrder(Arrays.asList(declarativeFolder.getChildren()), true)) {
207
                    if (f.hasExt("xml")) { // NOI18N
208
                        // For now, just assume it has the right DTD. Could check this if desired.
209
                        all.add(new MIMEResolverImpl(f));
210
                    }
211
                }
212
            }
213
214
            MIMEResolver[] toRet = all.toArray(new MIMEResolver[all.size()]);
199
215
200
            ERR.fine("Resolvers computed"); // NOI18N
216
            ERR.fine("Resolvers computed"); // NOI18N
201
217
(-)a/o.n.core/test/unit/src/org/netbeans/core/filesystems/MIMEResolverImplTest.java (-37 / +16 lines)
Lines 39-57 Link Here
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
42
package org.netbeans.core.filesystems;
42
package org.netbeans.modules.openide.filesystems.declmime;
43
43
44
import java.io.*;
45
import java.util.*;
46
import java.net.URL;
44
import java.net.URL;
47
import org.xml.sax.*;
45
import java.util.ArrayList;
48
import org.openide.loaders.*;
46
import java.util.List;
49
import org.openide.filesystems.*;
47
import org.netbeans.junit.NbTestCase;
50
import org.openide.util.*;
48
import org.openide.filesystems.FileObject;
51
import org.openide.util.lookup.*;
49
import org.openide.filesystems.FileSystem;
52
import org.openide.xml.*;
50
import org.openide.filesystems.FileUtil;
53
import org.openide.*;
51
import org.openide.filesystems.MIMEResolver;
54
import org.netbeans.junit.*;
52
import org.openide.filesystems.XMLFileSystem;
55
53
56
public class MIMEResolverImplTest extends NbTestCase {
54
public class MIMEResolverImplTest extends NbTestCase {
57
    List<MIMEResolver> resolvers;
55
    List<MIMEResolver> resolvers;
Lines 62-72 Link Here
62
    }
60
    }
63
    
61
    
64
    @SuppressWarnings("deprecation")
62
    @SuppressWarnings("deprecation")
63
    @Override
65
    protected void setUp() throws Exception {
64
    protected void setUp() throws Exception {
66
/*
67
        URL u = getClass().getProtectionDomain().getCodeSource().getLocation();
68
        u = new URL(u, "org/netbeans/core/filesystems/code-fs.xml");
69
*/
70
        URL u = this.getClass().getResource ("code-fs.xml");        
65
        URL u = this.getClass().getResource ("code-fs.xml");        
71
        FileSystem fs = new XMLFileSystem(u);
66
        FileSystem fs = new XMLFileSystem(u);
72
        
67
        
Lines 79-88 Link Here
79
            resolvers.add(createResolver(fos[i]));
74
            resolvers.add(createResolver(fos[i]));
80
        }
75
        }
81
        
76
        
82
/*
83
        u = getClass().getProtectionDomain().getCodeSource().getLocation();
84
        u = new URL(u, "org/netbeans/core/filesystems/data-fs.xml");
85
*/
86
        u = this.getClass().getResource ("data-fs.xml");                
77
        u = this.getClass().getResource ("data-fs.xml");                
87
        fs = new XMLFileSystem(u);
78
        fs = new XMLFileSystem(u);
88
        
79
        
Lines 91-123 Link Here
91
        FileUtil.setMIMEType("txt2", "text/plain; charset=us-ascii");        
82
        FileUtil.setMIMEType("txt2", "text/plain; charset=us-ascii");        
92
    }
83
    }
93
    
84
    
94
    public static void main(java.lang.String[] args) {
95
        junit.textui.TestRunner.run(suite());
96
    }
97
    
98
    public static NbTest suite() {
99
        NbTestSuite suite = new NbTestSuite(MIMEResolverImplTest.class);
100
        
101
        return suite;
102
    }
103
    
104
    
105
    private static MIMEResolver createResolver(FileObject fo) throws Exception {
85
    private static MIMEResolver createResolver(FileObject fo) throws Exception {
106
        if (fo == null) throw new NullPointerException();
86
        if (fo == null) throw new NullPointerException();
107
        return new MIMEResolverImpl.Impl(fo);
87
        return new MIMEResolverImpl(fo);
108
    }
88
    }
109
89
110
    private String resolve(FileObject fo) {
90
    private String resolve(FileObject fo) {
111
        Iterator it = resolvers.iterator();
91
        for (MIMEResolver r : resolvers) {
112
        while (it.hasNext()) {
113
            MIMEResolver r = (MIMEResolver) it.next();
114
            String s = r.findMIMEType(fo);
92
            String s = r.findMIMEType(fo);
115
            if (s != null) return s;
93
            if (s != null) return s;
116
        }
94
        }
117
        return null;
95
        return null;
118
    }
96
    }
119
    
97
    
120
    public void testDeclarativeMIME() throws Exception {
98
    public void testMultithreading() throws Exception {
121
        
99
        
122
        Object tl1 = new Object();
100
        Object tl1 = new Object();
123
        Object tl2 = new Object();
101
        Object tl2 = new Object();
Lines 144-156 Link Here
144
122
145
    private class TestThread extends Thread {
123
    private class TestThread extends Thread {
146
        
124
        
147
        Object lock;
125
        final Object lock;
148
        String fail;
126
        String fail;
149
        
127
        
150
        private TestThread(Object lock) {
128
        private TestThread(Object lock) {
151
            this.lock = lock;
129
            this.lock = lock;
152
        }
130
        }
153
        
131
        
132
        @Override
154
        public void run() {
133
        public void run() {
155
            String s;
134
            String s;
156
            FileObject fo = null;
135
            FileObject fo = null;
Lines 210-214 Link Here
210
    public void testIllegalXMLEncoding() {
189
    public void testIllegalXMLEncoding() {
211
        assertEquals("illegal-encoding.xml recognized as a XML file", "text/x-springconfig+xml", resolve(root.getFileObject("illegal-encoding", "xml")));
190
        assertEquals("illegal-encoding.xml recognized as a XML file", "text/x-springconfig+xml", resolve(root.getFileObject("illegal-encoding", "xml")));
212
    }
191
    }
213
        
192
214
}
193
}
(-)a/openide.filesystems/test/unit/src/org/openide/filesystems/MIMESupportTest.java (+17 lines)
Lines 45-50 Link Here
45
import java.io.IOException;
45
import java.io.IOException;
46
import java.io.InputStream;
46
import java.io.InputStream;
47
import java.io.OutputStream;
47
import java.io.OutputStream;
48
import java.io.PrintStream;
48
import java.lang.ref.WeakReference;
49
import java.lang.ref.WeakReference;
49
import java.util.Date;
50
import java.util.Date;
50
import java.util.Enumeration;
51
import java.util.Enumeration;
Lines 196-201 Link Here
196
        }
197
        }
197
    }
198
    }
198
    
199
    
200
    public void testDeclarativeMIMEResolvers() throws Exception {
201
        FileObject resolver = FileUtil.createData(Repository.getDefault().getDefaultFileSystem().getRoot(), "Services/MIMEResolver/r.xml");
202
        OutputStream os = resolver.getOutputStream();
203
        PrintStream ps = new PrintStream(os);
204
        ps.println("<!DOCTYPE MIME-resolver PUBLIC '-//NetBeans//DTD MIME Resolver 1.0//EN' 'http://www.netbeans.org/dtds/mime-resolver-1_0.dtd'>");
205
        ps.println("<MIME-resolver>");
206
        ps.println(" <file>");
207
        ps.println("  <ext name='foo'/>");
208
        ps.println("  <resolver mime='text/x-foo'/>");
209
        ps.println(" </file>");
210
        ps.println("</MIME-resolver>");
211
        os.close();
212
        FileObject foo = FileUtil.createMemoryFileSystem().getRoot().createData("x.foo");
213
        assertEquals("text/x-foo", foo.getMIMEType());
214
    }
215
199
    public static class TestLookup extends ProxyLookup {
216
    public static class TestLookup extends ProxyLookup {
200
        public TestLookup() {
217
        public TestLookup() {
201
            super();
218
            super();

Return to bug 138846