blob: 5bfed1b0621120b46d79d6f7f3cdbaafdcedf36b [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.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();
}
}
}
}