org.netbeans.modules.openide.filesystems.RecognizeInstanceFiles Maven / Gradle / Ivy
/*
* 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.openide.filesystems;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openide.filesystems.FileAttributeEvent;
import org.openide.filesystems.FileChangeListener;
import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileRenameEvent;
import org.openide.filesystems.FileStateInvalidException;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.spi.CustomInstanceFactory;
import org.openide.util.BaseUtilities;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;
import org.openide.util.lookup.ServiceProvider;
import org.openide.util.lookup.implspi.NamedServicesProvider;
/** Interface for core/startup to provide lookup over system filesystem.
*
* @author Jaroslav Tulach
*/
@ServiceProvider(service=NamedServicesProvider.class, position=500)
public final class RecognizeInstanceFiles extends NamedServicesProvider {
private static final Logger LOG = Logger.getLogger(RecognizeInstanceFiles.class.getName());
@Override
public Lookup create(String path) {
return new OverFiles(path);
}
@Override
public T lookupObject(String path, Class type) {
FileObject fo = FileUtil.getConfigFile(path);
if (fo != null && fo.isData()) {
return FOItem.createInstanceFor(fo, type);
}
return null;
}
private static final class OverFiles extends ProxyLookup
implements FileChangeListener {
private final String path;
private final FileChangeListener weakL;
private final AbstractLookup.Content content;
private final AbstractLookup lkp;
public OverFiles(String path) {
this(path, new ArrayList(), new AbstractLookup.Content());
}
private OverFiles(String path, List items, AbstractLookup.Content cnt) {
this(path, items, new AbstractLookup(cnt), cnt);
}
private OverFiles(String path, List items, AbstractLookup lkp, AbstractLookup.Content cnt) {
super(computeDelegates(path, items, lkp));
this.path = path;
this.lkp = lkp;
this.content = cnt;
this.content.setPairs(order(items));
FileSystem fs = null;
try {
fs = FileUtil.getSystemConfigRoot().getFileSystem();
} catch (FileStateInvalidException ex) {
Exceptions.printStackTrace(ex);
}
this.weakL = FileUtil.weakFileChangeListener(this, fs);
fs.addFileChangeListener(weakL);
}
private static List order(List items) {
Map m = new LinkedHashMap();
for (FOItem item : items) {
m.put(item.fo, item);
}
List files = FileUtil.getOrder(m.keySet(), true);
List r = new ArrayList(files.size());
for (FileObject f : files) {
r.add(m.get(f));
}
return r;
}
private void refresh(FileEvent ev) {
if (!(ev.getFile().getPath() + "/").startsWith(path)) {
return;
}
List items = new ArrayList();
Lookup[] delegates = computeDelegates(path, items, lkp);
this.content.setPairs(order(items));
this.setLookups(delegates);
}
private static Lookup[] computeDelegates(String p, List items, Lookup lkp) {
FileObject fo = FileUtil.getConfigFile(p);
List delegates = new LinkedList();
delegates.add(lkp);
if (fo != null) {
for (FileObject f : fo.getChildren()) {
if (f.isFolder()) {
delegates.add(new OverFiles(f.getPath()));
} else {
if (f.hasExt("shadow")) {
Object real = f.getAttribute("originalFile"); // NOI18N
if (real instanceof String) {
f = FileUtil.getConfigFile((String)real);
}
}
if (f.hasExt("instance") || f.getAttribute("instanceCreate") != null) {
items.add(new FOItem(f));
}
}
}
}
ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
if (l == null) {
l = Thread.currentThread().getContextClassLoader();
}
if (l == null) {
l = RecognizeInstanceFiles.class.getClassLoader();
}
delegates.add(
Lookups.metaInfServices(l, "META-INF/namedservices/" + p) // NOI18N
);
return delegates.toArray(new Lookup[0]);
}
public void fileFolderCreated(FileEvent fe) {
refresh(fe);
}
public void fileDataCreated(FileEvent fe) {
refresh(fe);
}
public void fileChanged(FileEvent fe) {
refresh(fe);
}
public void fileDeleted(FileEvent fe) {
refresh(fe);
}
public void fileRenamed(FileRenameEvent fe) {
refresh(fe);
}
public void fileAttributeChanged(FileAttributeEvent fe) {
refresh(fe);
}
} // end of OverFiles
private static volatile Lookup.Result factories;
private static Collection extends CustomInstanceFactory> getInstanceFactories() {
Lookup.Result fr;
if ((fr = factories) == null) {
factories = fr = Lookup.getDefault().lookupResult(CustomInstanceFactory.class);
}
return fr.allInstances();
}
public static final T createInstance(Class type) throws InstantiationException,
IllegalAccessException, InvocationTargetException, NoSuchMethodException {
T r = null;
for (CustomInstanceFactory fif : getInstanceFactories()) {
r = (T)fif.createInstance(type);
if (r != null) {
break;
}
}
if (r == null) {
Constructor init = type.getDeclaredConstructor();
init.setAccessible(true);
r = init.newInstance();
}
return r;
}
private static final class FOItem extends AbstractLookup.Pair
© 2015 - 2025 Weber Informatics LLC | Privacy Policy