Java tutorial
/* * Copyright 2017 Eric Bishton * * Licensed 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 com.intellij.plugins.haxe.haxelib; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.plugins.haxe.lang.psi.HaxeClass; import com.intellij.plugins.haxe.util.HaxeDebugLogger; import com.intellij.plugins.haxe.util.HaxeFileUtil; import org.apache.commons.lang.NotImplementedException; import org.apache.log4j.Level; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.security.InvalidParameterException; import java.util.*; public class HaxeLibrary { private static HaxeDebugLogger LOG = HaxeDebugLogger.getLogger(); static { LOG.setLevel(Level.DEBUG); } // Remove when finished debugging. private static String CURRENT_DIR = "."; final private HaxelibLibraryCache myCache; final private String myName; final private String myLibraryRoot; final private String myRelativeClasspath; final private HaxelibMetadata myMetadata; final private HaxelibSemVer mySemVer; // TODO: Add the extraParams.hxml data here. Use the hxml parser; see LimeUtil.getLimeProjectModel() as an example. private HaxeLibrary(@NotNull String name, @NotNull VirtualFile libraryRoot, @NotNull HaxelibLibraryCache owner) { myCache = owner; myLibraryRoot = libraryRoot.getUrl(); myMetadata = HaxelibMetadata.load(libraryRoot); HaxeLibraryInfo pathInfo = HaxelibUtil.deriveLibraryInfoFromPath(owner.getSdk(), libraryRoot.getPath()); String mdname = myMetadata.getName(); if (null != mdname && !mdname.isEmpty()) { myName = mdname; } else if (!name.isEmpty()) { myName = name; } else { myName = pathInfo == null ? "" : pathInfo.getName(); } HaxelibSemVer semVer = HaxelibSemVer.create(myMetadata.getVersion()); if (HaxelibSemVer.ZERO_VERSION == semVer && pathInfo != null) { semVer = pathInfo.getVersion(); } mySemVer = semVer; String cp = myMetadata.getClasspath(); if ((null == cp || cp.isEmpty()) && pathInfo != null) { cp = pathInfo.getClasspath(); } if (null != cp && !cp.isEmpty()) { myRelativeClasspath = cp; } else { myRelativeClasspath = CURRENT_DIR; } } /** * Get the list of libraries that this library depends upon (but not /their/ dependents). * * Private because it's only used by collectDependents. * Returns a List instead of a HaxeLibraryList to keep synchronized access down. */ @NotNull private List<HaxeLibraryDependency> getDirectDependents() { List<HaxelibMetadata.Dependency> mdDependencies = myMetadata.getDependencies(); if (null == mdDependencies || mdDependencies.isEmpty()) { return Collections.emptyList(); } List<HaxeLibraryDependency> dependencies = new ArrayList<HaxeLibraryDependency>(mdDependencies.size()); for (HaxelibMetadata.Dependency md : mdDependencies) { HaxeLibraryDependency newdep = new HaxeLibraryDependency(myCache, md.getName(), md.getVersion(), this); dependencies.add(newdep); } return dependencies; } /** * Get all dependent libraries in search order. */ @NotNull public HaxeLibraryList collectDependents() { LinkedHashMap<String, HaxeLibraryDependency> collection = new LinkedHashMap<String, HaxeLibraryDependency>(); collectDependentsInternal(collection); HaxeLibraryList list = new HaxeLibraryList(myCache.getSdk()); for (HaxeLibraryDependency dep : collection.values()) { list.add(dep); } return list; } private void collectDependentsInternal( /*modifies*/ final @NotNull LinkedHashMap<String, HaxeLibraryDependency> collection) { List<HaxeLibraryDependency> dependencies = getDirectDependents(); for (HaxeLibraryDependency dependency : dependencies) { if (!collection.containsKey(dependency.getKey())) { // Don't go down the same path again... // TODO: Deal with version mismatches here. Add multiple versions, but don't add a specific version if the latest version is equal to it. collection.put(dependency.getKey(), dependency); HaxeLibrary depLib = dependency.getLibrary(); if (null != depLib) { depLib.collectDependentsInternal(collection); } // TODO: Else mark dependency unfulfilled somehow?? } else { HaxeLibraryDependency contained = collection.get(dependency.getKey()); LOG.assertLog(contained != null, "Couldn't get a contained object."); if (contained != null) { contained.addReliant(dependency); } } } } /** * Get the internal name of the library. */ @NotNull public String getName() { return myName; } /** * Get the display name of the library. */ @NotNull public String getPresentableName() { // TODO: Figure out what extra decorations we might need, like the version, 'dependency of', etc. return getName(); } @Nullable public HaxeClasspath getClasspathEntries() { HaxeClasspath cp = new HaxeClasspath(); cp.add(getSourceRoot()); return cp; } @NotNull public HaxeClasspathEntry getSourceRoot() { if (CURRENT_DIR == myRelativeClasspath) { return getLibraryRoot(); } return new HaxeClasspathEntry(myName, HaxeFileUtil.joinPath(myLibraryRoot, myRelativeClasspath)); } @NotNull public HaxeClasspathEntry getLibraryRoot() { return new HaxeClasspathEntry(myName, myLibraryRoot); } @NotNull public HaxelibSemVer getVersion() { return mySemVer; } /** * Load a library from disk. This *DOES NOT* place the library into the library manager. * * @param libName - name of the library (as haxelib understands it) to load. * @return the loaded HaxeLibrary of the given name; null if not found. */ @Nullable public static HaxeLibrary load(HaxelibLibraryCache owner, String libName, Sdk sdk) { // Ask haxelib for the path to this library. VirtualFile libraryRoot = HaxelibUtil.getLibraryRoot(sdk, libName); if (null == libraryRoot) { // XXX: This case might occur if the library is not managed by haxelib, but then // that should be a classpath, not a lib. return null; } try { return new HaxeLibrary(libName, libraryRoot, owner); } catch (InvalidParameterException e) { ; // libName must not have been an url } return null; } /** * Create a new reference for this library. * @param isManaged whether or not this reference is a "managed reference". */ @NotNull public HaxeLibraryReference createReference(boolean isManaged) { return new HaxeLibraryReference(myCache, myName, mySemVer, isManaged); } /** * Create a new unmanaged reference for this library. */ @NotNull public HaxeLibraryReference createReference() { return new HaxeLibraryReference(myCache, myName, mySemVer); } @NotNull public HaxeLibraryReference createReference(HaxelibSemVer override) { return new HaxeLibraryReference(myCache, myName, override); } /** * Test whether this library is effectively the same as a Library appearing * in IDEA's library tables. * * @param lib - Library to test. * @return true if this library uses the same sources as the IDEA library; false otherwise. */ public boolean matchesIdeaLib(Library lib) { if (null == lib) { return false; } HaxeClasspath cp = getClasspathEntries(); VirtualFile[] sources = lib.getFiles(OrderRootType.SOURCES); for (VirtualFile file : sources) { if (!cp.containsUrl(file.getUrl())) { return false; } } return cp.size() == sources.length; } }