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 |
/** |