blob: d720879621b67e558c54d5f4cea58fb8ea693b37 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.editor.mimelookup.impl;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.spi.editor.mimelookup.InstanceProvider;
import org.netbeans.spi.editor.mimelookup.MimeLocation;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
/**
*
* @author vita
*/
public class SwitchLookup extends Lookup {
private static final Logger LOG = Logger.getLogger(SwitchLookup.class.getName());
/* package */ static final String ROOT_FOLDER = "Editors"; //NOI18N
private MimePath mimePath;
private final String LOCK = new String("SwitchLookup.LOCK"); //NOI18N
private Map<Class<?>,Lookup> classLookups = new HashMap<Class<?>, Lookup>();
private Map<List<String>,Lookup> pathsLookups = new HashMap<List<String>,Lookup>();
public SwitchLookup(MimePath mimePath) {
super();
this.mimePath = mimePath;
}
public <T> Lookup.Result<T> lookup(Lookup.Template<T> template) {
return findLookup(template.getType()).lookup(template);
}
public <T> T lookup(Class<T> clazz) {
return findLookup(clazz).lookup(clazz);
}
private Lookup findLookup(Class<?> clazz) {
synchronized (LOCK) {
Lookup lookup = classLookups.get(clazz);
if (lookup == null) {
// Create lookup
lookup = createLookup(clazz);
classLookups.put(clazz, lookup);
}
return lookup;
}
}
private Lookup createLookup(Class<?> forClass) {
MimeLocation loc = forClass.getAnnotation(MimeLocation.class);
if (loc == null) {
loc = new MimeLocation() {
@Override
public String subfolderName() {
return null;
}
@Override
public Class<? extends InstanceProvider> instanceProviderClass() {
return null;
}
@Override
public Class<? extends Annotation> annotationType() {
return MimeLocation.class;
}
};
}
List<String> paths = computePaths(mimePath, ROOT_FOLDER, loc.subfolderName());
Lookup lookup;
if (loc.instanceProviderClass() != null && loc.instanceProviderClass() != InstanceProvider.class) {
try {
// Get a lookup for the new instance provider
lookup = getLookupForProvider(paths, loc.instanceProviderClass().newInstance());
} catch (InstantiationException ex) {
Exceptions.printStackTrace(ex);
lookup = Lookup.EMPTY;
} catch (IllegalAccessException ex) {
Exceptions.printStackTrace(ex);
lookup = Lookup.EMPTY;
}
} else {
// Get a lookup for the new paths
lookup = getLookupForPaths(paths);
}
return lookup;
}
private Lookup getLookupForPaths(List<String> paths) {
Lookup lookup = pathsLookups.get(paths);
if (lookup == null) {
lookup = new FolderPathLookup(paths.toArray(new String[paths.size()]));
pathsLookups.put(paths, lookup);
}
return lookup;
}
private Lookup getLookupForProvider(List<String> paths, InstanceProvider instanceProvider) {
return new InstanceProviderLookup(paths.toArray(new String[paths.size()]), instanceProvider);
}
private static List<String> computePaths(MimePath mimePath, String prefixPath, String suffixPath) {
try {
Method m = MimePath.class.getDeclaredMethod("getInheritedPaths", String.class, String.class); //NOI18N
m.setAccessible(true);
@SuppressWarnings("unchecked")
List<String> paths = (List<String>) m.invoke(mimePath, prefixPath, suffixPath);
return paths;
} catch (Exception e) {
LOG.log(Level.WARNING, "Can't call org.netbeans.api.editor.mimelookup.MimePath.getInheritedPaths method.", e); //NOI18N
}
// No inherited mimepaths, provide at least something
StringBuilder sb = new StringBuilder();
if (prefixPath != null && prefixPath.length() > 0) {
sb.append(prefixPath);
}
if (mimePath.size() > 0) {
if (sb.length() > 0) {
sb.append('/'); //NOI18N
}
sb.append(mimePath.getPath());
}
if (suffixPath != null && suffixPath.length() > 0) {
if (sb.length() > 0) {
sb.append('/'); //NOI18N
}
sb.append(suffixPath);
}
return Collections.singletonList(sb.toString());
}
}