| /* |
| * 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.javafx2.platform; |
| |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.io.File; |
| import java.net.MalformedURLException; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.util.*; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.swing.event.ChangeListener; |
| import org.netbeans.api.annotations.common.CheckForNull; |
| import org.netbeans.api.annotations.common.NonNull; |
| import org.netbeans.api.java.platform.JavaPlatform; |
| import org.netbeans.api.java.platform.JavaPlatformManager; |
| import org.netbeans.api.java.platform.Specification; |
| import org.netbeans.api.java.queries.JavadocForBinaryQuery; |
| import org.netbeans.api.java.queries.JavadocForBinaryQuery.Result; |
| import org.netbeans.modules.javafx2.platform.api.JavaFxRuntimeInclusion; |
| import org.netbeans.spi.java.queries.JavadocForBinaryQueryImplementation; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.util.ChangeSupport; |
| import org.openide.util.Exceptions; |
| import org.openide.util.Parameters; |
| import org.openide.util.WeakListeners; |
| import org.openide.util.lookup.ServiceProvider; |
| |
| /** |
| * JavadocForBinaryQuery implementation for JFX platform |
| * @author Tomas Zezula |
| */ |
| @ServiceProvider(service=JavadocForBinaryQueryImplementation.class, position=11000) |
| public class JavaFXPlatformJavadoc implements JavadocForBinaryQueryImplementation { |
| |
| private static final Logger LOG = Logger.getLogger(JavaFXPlatformJavadoc.class.getName()); |
| private final ResultCache cache; |
| |
| public JavaFXPlatformJavadoc() { |
| cache = new ResultCache(); |
| } |
| |
| |
| |
| @Override |
| public Result findJavadoc(@NonNull final URL binaryRoot) { |
| final long st = System.currentTimeMillis(); |
| try { |
| Parameters.notNull("binaryRoot", binaryRoot); //NOI18N |
| final URL archiveURL = FileUtil.getArchiveFile(binaryRoot); |
| if (archiveURL == null) { |
| LOG.log( |
| Level.FINE, |
| "Ignoring {0}, not an archvive.", //NOI18N |
| binaryRoot); |
| return null; |
| } |
| if (!"file".equals(archiveURL.getProtocol())) { //NOI18N |
| LOG.log( |
| Level.FINE, |
| "Ignoring {0}, not a local file.", //NOI18N |
| binaryRoot); |
| return null; |
| } |
| try { |
| final File archiveFile = new File (archiveURL.toURI()); |
| if (!Utils.getJavaFxRuntimeArchiveName().equals(archiveFile.getName())) { |
| LOG.log( |
| Level.FINE, |
| "Ignoring {0}, not an JavaFX runtime.", //NOI18N |
| binaryRoot); |
| return null; |
| } |
| return cache.getResult(archiveFile); |
| } catch (URISyntaxException e) { |
| Exceptions.printStackTrace(e); |
| return null; |
| } |
| } finally { |
| final long et = System.currentTimeMillis(); |
| LOG.log( |
| Level.FINER, |
| "findJavadoc({0}) took {1}ms.", //NOI18N |
| new Object[]{ |
| binaryRoot, |
| et-st |
| }); |
| } |
| } |
| |
| //@ThreadSafe |
| private static final class ResultCache implements PropertyChangeListener { |
| |
| private static final Result UNKNOWN = new Result() { |
| @Override |
| public URL[] getRoots() { |
| return new URL[0]; |
| } |
| @Override |
| public void addChangeListener(ChangeListener l) { |
| } |
| @Override |
| public void removeChangeListener(ChangeListener l) { |
| } |
| }; |
| |
| //@GuaredBy("results") |
| private final Map<File, Result> results = |
| Collections.synchronizedMap(new HashMap<File, Result>()); |
| |
| |
| |
| ResultCache() { |
| final JavaPlatformManager jpm = JavaPlatformManager.getDefault(); |
| jpm.addPropertyChangeListener(WeakListeners.propertyChange(this, jpm)); |
| } |
| |
| @CheckForNull |
| Result getResult(@NonNull final File file) { |
| Parameters.notNull("file", file); //NOI18N |
| Result res = results.get(file); |
| if (res == null) { |
| final Collection<? extends JavaPlatform> jps = findJavaPlatforms(file); |
| if (!jps.isEmpty() && |
| !JavaFxRuntimeInclusion.forPlatform(jps.iterator().next()).isIncludedOnClassPath()) { |
| res = new ResultImpl(jps); |
| } else { |
| res = UNKNOWN; |
| } |
| synchronized (results) { |
| final Result tmp = results.get(file); |
| if (tmp == null) { |
| results.put(file, res); |
| } else { |
| res = tmp; |
| } |
| } |
| } |
| return res == UNKNOWN ? null : res; |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(evt.getPropertyName())) { |
| results.clear(); |
| } |
| } |
| |
| @NonNull |
| private Collection<? extends JavaPlatform> findJavaPlatforms(@NonNull final File jfxrt) { |
| final JavaPlatform[] jps = JavaPlatformManager.getDefault().getPlatforms( |
| null, |
| new Specification( |
| "j2se", //NOI18N |
| null)); |
| final Collection<JavaPlatform> res = new ArrayList<JavaPlatform>(jps.length); |
| final FileObject jfxrfFo = FileUtil.toFileObject(jfxrt); |
| if (jfxrfFo != null) { |
| for (JavaPlatform jp : jps) { |
| for (FileObject installFolder : jp.getInstallFolders()) { |
| if (FileUtil.isParentOf(installFolder, jfxrfFo)) { |
| res.add(jp); |
| } |
| } |
| } |
| } |
| return res; |
| } |
| |
| } |
| |
| private static final class ResultImpl implements JavadocForBinaryQuery.Result, PropertyChangeListener { |
| |
| private final Collection<? extends JavaPlatform> plaforms; |
| private final ChangeSupport support; |
| |
| ResultImpl(@NonNull final Collection<? extends JavaPlatform> platforms) { |
| Parameters.notNull("platforms", platforms); //NOI18N |
| this.plaforms = platforms; |
| for (JavaPlatform jp : this.plaforms) { |
| jp.addPropertyChangeListener(WeakListeners.propertyChange(this, jp)); |
| } |
| this.support = new ChangeSupport(this); |
| } |
| |
| @Override |
| public URL[] getRoots() { |
| try { |
| final long st = System.currentTimeMillis(); |
| final Set<URI> collector = new LinkedHashSet<URI>(); |
| for (JavaPlatform jp : plaforms) { |
| for (URL jdoc : jp.getJavadocFolders()) { |
| collector.add(jdoc.toURI()); |
| } |
| } |
| final URL[] res = new URL[collector.size()]; |
| int i = 0; |
| for (URI uri : collector) { |
| res[i++] = uri.toURL(); |
| } |
| final long et = System.currentTimeMillis(); |
| LOG.log( |
| Level.FINER, |
| "getRoots() -> {0} took: {1}ms", //NOI18N |
| new Object[]{ |
| collector, |
| et-st |
| }); |
| return res; |
| } catch (URISyntaxException e) { |
| Exceptions.printStackTrace(e); |
| } catch (MalformedURLException e) { |
| Exceptions.printStackTrace(e); |
| } |
| return new URL[0]; |
| } |
| |
| @Override |
| public void addChangeListener(@NonNull final ChangeListener l) { |
| Parameters.notNull("l", l); //NOI18N |
| support.addChangeListener(l); |
| } |
| |
| @Override |
| public void removeChangeListener(@NonNull final ChangeListener l) { |
| Parameters.notNull("l", l); //NOI18N |
| support.removeChangeListener(l); |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (JavaPlatform.PROP_JAVADOC_FOLDER.equals(evt.getPropertyName())) { |
| support.fireChange(); |
| } |
| } |
| |
| } |
| |
| } |