diff options
Diffstat (limited to 'plugins/eclipse/jps-plugin/src')
5 files changed, 526 insertions, 0 deletions
diff --git a/plugins/eclipse/jps-plugin/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension b/plugins/eclipse/jps-plugin/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension new file mode 100644 index 000000000000..eeebef91e18b --- /dev/null +++ b/plugins/eclipse/jps-plugin/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelSerializerExtension @@ -0,0 +1 @@ +org.jetbrains.jps.eclipse.model.JpsEclipseModelSerializerExtension
\ No newline at end of file diff --git a/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseClasspathReader.java b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseClasspathReader.java new file mode 100644 index 000000000000..b9f431645c50 --- /dev/null +++ b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseClasspathReader.java @@ -0,0 +1,274 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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 org.jetbrains.jps.eclipse.model; + +import com.intellij.openapi.components.ExpandMacroToPathMap; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.HashSet; +import org.jdom.Element; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.eclipse.*; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.java.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsOrderRootType; +import org.jetbrains.jps.model.module.*; +import org.jetbrains.jps.model.serialization.JpsMacroExpander; +import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.*; + +/** + * User: anna + * Date: 10/29/12 + */ +class JpsEclipseClasspathReader extends AbstractEclipseClasspathReader<JpsModule> { + private static final Logger LOG = Logger.getInstance(JpsEclipseClasspathReader.class); + private final Map<String, String> myLibLevels; + + public JpsEclipseClasspathReader(String rootPath, + @Nullable List<String> currentRoots, + @Nullable Set<String> moduleNames, + Map<String, String> levels) { + super(rootPath, currentRoots, moduleNames); + myLibLevels = levels; + } + + @Override + protected String prepareValidUrlInsideJar(String url) { + //strip path inside jar + final String jarSeparator = "!/"; + final int localPathEndIdx = url.indexOf(jarSeparator); + if (localPathEndIdx > -1) { + return url.substring(0, localPathEndIdx + jarSeparator.length()); + } + return url; + } + + @Override + protected void addNamedLibrary(JpsModule rootModel, + Collection<String> unknownLibraries, + boolean exported, + String name, + boolean applicationLevel) { + if (LOG.isDebugEnabled()) { + LOG.debug("loading " + rootModel.getName() + ": adding " + (applicationLevel ? "application" : "project") + " library '" + name + "'"); + } + JpsElementFactory factory = JpsElementFactory.getInstance(); + JpsLibraryReference libraryReference; + final String level = myLibLevels.get(name); + libraryReference = level != null ? factory.createLibraryReference(name, JpsLibraryTableSerializer.createLibraryTableReference(level)) + : factory.createLibraryReference(name, factory.createGlobalReference()); + final JpsLibraryDependency dependency = rootModel.getDependenciesList().addLibraryDependency(libraryReference); + setLibraryEntryExported(dependency, exported); + } + + @Override + protected void addInvalidModuleEntry(JpsModule rootModel, boolean exported, String moduleName) { + final JpsElementFactory elementFactory = JpsElementFactory.getInstance(); + final JpsDependenciesList dependenciesList = rootModel.getDependenciesList(); + final JpsModuleDependency dependency = dependenciesList.addModuleDependency(elementFactory.createModuleReference(moduleName)); + final JpsJavaDependencyExtension extension = getService().getOrCreateDependencyExtension(dependency); + extension.setExported(exported); + } + + @Override + protected void setUpModuleJdk(JpsModule rootModel, + Collection<String> unknownJdks, + EclipseModuleManager eclipseModuleManager, + String jdkName) { + if (LOG.isDebugEnabled()) { + LOG.debug("loading " + rootModel.getName() + ": set module jdk " + jdkName); + } + final JpsDependenciesList dependenciesList = rootModel.getDependenciesList(); + dependenciesList.addSdkDependency(JpsJavaSdkType.INSTANCE); + if (jdkName != null) { + JpsSdkTableSerializer.setSdkReference(rootModel.getSdkReferencesTable(), jdkName, JpsJavaSdkType.INSTANCE); + } + } + + @Override + protected void addSourceFolder(JpsModule rootModel, String srcUrl, boolean testFolder) { + rootModel.addSourceRoot(srcUrl, testFolder ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE); + } + + @Override + protected void addSourceFolderToCurrentContentRoot(JpsModule rootModel, String srcUrl, boolean testFolder) { + rootModel.addSourceRoot(srcUrl, testFolder ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE); + } + + @Override + protected void addJUnitDefaultLib(JpsModule rootModel, String junitName, ExpandMacroToPathMap macroMap) { + final String ideaHome = macroMap.substitute("$APPLICATION_HOME_DIR$", SystemInfo.isFileSystemCaseSensitive); + final FilenameFilter junitFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("junit"); + } + }; + File[] junitJars = new File(ideaHome, "lib").listFiles(junitFilter); + if (junitJars == null || junitJars.length == 0) { + junitJars = new File(new File(ideaHome, "community"), "lib").listFiles(junitFilter); + } + if (junitJars != null && junitJars.length > 0) { + final boolean isJUnit4 = junitName.contains("4"); + File junitJar = null; + for (File jar : junitJars) { + final boolean isCurrentJarV4 = jar.getName().contains("4"); + if (isCurrentJarV4 && isJUnit4 || !isCurrentJarV4 && !isJUnit4) { + junitJar = jar; + break; + } + } + if (junitJar != null) { + final JpsLibrary jpsLibrary = rootModel.addModuleLibrary(junitName, JpsJavaLibraryType.INSTANCE); + jpsLibrary.addRoot(pathToUrl(junitJar.getPath()), JpsOrderRootType.COMPILED); + final JpsDependenciesList dependenciesList = rootModel.getDependenciesList(); + dependenciesList.addLibraryDependency(jpsLibrary); + } + } + } + + @Override + protected void addModuleLibrary(JpsModule rootModel, + Element element, + boolean exported, + String libName, + String url, + String srcUrl, + ExpandMacroToPathMap macroMap) { + final JpsLibrary jpsLibrary = rootModel.addModuleLibrary(libName, JpsJavaLibraryType.INSTANCE); + final JpsDependenciesList dependenciesList = rootModel.getDependenciesList(); + final JpsLibraryDependency dependency = dependenciesList.addLibraryDependency(jpsLibrary); + url = StringUtil.trimStart(url, "file://"); + final String linked = expandLinkedResourcesPath(url, macroMap); + if (linked != null) { + url = pathToUrl(linked); + } + else { + url = expandEclipsePath2Url(rootModel, url); + } + LOG.debug("loading " + rootModel.getName() + ": adding module library " + libName + ": " + url); + jpsLibrary.addRoot(url, JpsOrderRootType.COMPILED); + + setLibraryEntryExported(dependency, exported); + } + + @Override + protected String expandEclipsePath2Url(JpsModule rootModel, String path) { + + String url = null; + if (new File(path).exists()) { //absolute path + url = pathToUrl(path); + } + else { + final String relativePath = new File(myRootPath, path).getPath(); //inside current project + final File file = new File(relativePath); + if (file.exists()) { + url = pathToUrl(relativePath); + } + else if (path.startsWith("/")) { //relative to other project + final String moduleName = EPathCommonUtil.getRelativeModuleName(path); + final String relativeToRootPath = EPathCommonUtil.getRelativeToModulePath(path); + url = EPathCommonUtil.expandEclipseRelative2ContentRoots(myCurrentRoots, moduleName, relativeToRootPath); + } + } + if (url == null) { + url = pathToUrl(path); + } + + return prepareValidUrlInsideJar(url); + } + + + @Override + protected int rearrange(JpsModule rootModel) { + return 0; + } + + public void readClasspath(JpsModule model, + final String testPattern, + Element classpathElement, JpsMacroExpander expander) throws IOException { + LOG.debug("start loading classpath for " + model.getName()); + for (Object o : classpathElement.getChildren(EclipseXml.CLASSPATHENTRY_TAG)) { + try { + readClasspathEntry(model, new ArrayList<String>(), new ArrayList<String>(), new HashSet<String>(), new HashSet<String>(), + testPattern, (Element)o, 0, EclipseModuleManager.EMPTY, expander.getExpandMacroMap()); + } + catch (ConversionException e) { + throw new IOException(e); + } + } + boolean foundSdkDependency = false; + JpsDependenciesList dependenciesList = model.getDependenciesList(); + for (JpsDependencyElement element : dependenciesList.getDependencies()) { + if (element instanceof JpsSdkDependency) { + foundSdkDependency = true; + break; + } + } + if (!foundSdkDependency) { + dependenciesList.addSdkDependency(JpsJavaSdkType.INSTANCE); + } + if (LOG.isDebugEnabled()) { + String name = model.getName(); + LOG.debug("finished loading classpath for " + name + " (" + dependenciesList.getDependencies().size() + " items):"); + for (JpsDependencyElement element : dependenciesList.getDependencies()) { + LOG.debug(" [" + name + "]:" + element.toString()); + } + } + } + + @Nullable + private String expandLinkedResourcesPath(final String path, ExpandMacroToPathMap expander) { + final EclipseProjectFinder.LinkedResource linkedResource = EclipseProjectFinder.findLinkedResource(myRootPath, path); + if (linkedResource != null) { + if (linkedResource.containsPathVariable()) { + final String toPathVariableFormat = + getVariableRelatedPath(linkedResource.getVariableName(), linkedResource.getRelativeToVariablePath()); + return expander.substitute(toPathVariableFormat, SystemInfo.isFileSystemCaseSensitive); + } + return linkedResource.getLocation(); + } + return null; + } + + public void setupOutput(JpsModule rootModel, final String path) { + final JpsJavaModuleExtension extension = getService().getOrCreateModuleExtension(rootModel); + String outputUrl = pathToUrl(path); + extension.setOutputUrl(outputUrl); + extension.setTestOutputUrl(outputUrl); + //extension.setInheritOutput(false); + + rootModel.getDependenciesList().addModuleSourceDependency(); + } + + private static void setLibraryEntryExported(final JpsDependencyElement dependency, boolean exported) { + final JpsJavaDependencyExtension extension = getService().getOrCreateDependencyExtension(dependency); + extension.setExported(exported); + } + + private static JpsJavaExtensionService getService() { + return JpsJavaExtensionService.getInstance(); + } +} diff --git a/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseClasspathSerializer.java b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseClasspathSerializer.java new file mode 100644 index 000000000000..0da330c5437a --- /dev/null +++ b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseClasspathSerializer.java @@ -0,0 +1,66 @@ +package org.jetbrains.jps.eclipse.model; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.containers.HashSet; +import org.jdom.Document; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.eclipse.EclipseXml; +import org.jetbrains.jps.model.library.sdk.JpsSdkType; +import org.jetbrains.jps.model.module.JpsDependenciesList; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.JpsMacroExpander; +import org.jetbrains.jps.model.serialization.module.JpsModuleClasspathSerializer; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author nik + */ +public class JpsEclipseClasspathSerializer extends JpsModuleClasspathSerializer { + @NonNls public static final String CLASSPATH_STORAGE_ID = "eclipse"; + private static final Logger LOG = Logger.getInstance(JpsEclipseClasspathSerializer.class); + + public JpsEclipseClasspathSerializer() { + super(CLASSPATH_STORAGE_ID); + } + + @Override + public void loadClasspath(@NotNull JpsModule module, + @Nullable String classpathDir, + @NotNull String baseModulePath, + JpsMacroExpander expander, + List<String> paths, + JpsSdkType<?> projectSdkType) { + final JpsDependenciesList dependenciesList = module.getDependenciesList(); + dependenciesList.clear(); + try { + if (classpathDir == null) classpathDir = baseModulePath; + final File classpathFile = new File(classpathDir, EclipseXml.DOT_CLASSPATH_EXT); + if (!classpathFile.exists()) return; //no classpath file - no compilation + + final String eml = module.getName() + EclipseXml.IDEA_SETTINGS_POSTFIX; + final File emlFile = new File(baseModulePath, eml); + final Map<String, String> levels = new HashMap<String, String>(); + if (emlFile.isFile()) { + final Document emlDocument = JDOMUtil.loadDocument(emlFile); + final Element root = emlDocument.getRootElement(); + new JpsIdeaSpecificSettings(expander).readIDEASpecific(root, module, projectSdkType, levels); + } + + final Document document = JDOMUtil.loadDocument(classpathFile); + final JpsEclipseClasspathReader reader = new JpsEclipseClasspathReader(classpathDir, paths, new HashSet<String>(), levels); + reader.readClasspath(module, null, document.getRootElement(), expander);//todo + } + catch (Exception e) { + LOG.info(e); + throw new RuntimeException(e); + } + } +} diff --git a/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseModelSerializerExtension.java b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseModelSerializerExtension.java new file mode 100644 index 000000000000..d42eeb35bca9 --- /dev/null +++ b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsEclipseModelSerializerExtension.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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 org.jetbrains.jps.eclipse.model; + +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; +import org.jetbrains.jps.model.serialization.module.JpsModuleClasspathSerializer; + +/** + * @author nik + */ +public class JpsEclipseModelSerializerExtension extends JpsModelSerializerExtension { + private static final JpsEclipseClasspathSerializer CLASSPATH_SERIALIZER = new JpsEclipseClasspathSerializer(); + + @Nullable + @Override + public JpsModuleClasspathSerializer getClasspathSerializer() { + return CLASSPATH_SERIALIZER; + } +} diff --git a/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsIdeaSpecificSettings.java b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsIdeaSpecificSettings.java new file mode 100644 index 000000000000..e1e1b8506a70 --- /dev/null +++ b/plugins/eclipse/jps-plugin/src/org/jetbrains/jps/eclipse/model/JpsIdeaSpecificSettings.java @@ -0,0 +1,152 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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 org.jetbrains.jps.eclipse.model; + +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.ArrayUtil; +import org.jdom.Element; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.eclipse.IdeaXml; +import org.jetbrains.idea.eclipse.conversion.AbstractIdeaSpecificSettings; +import org.jetbrains.jps.model.java.*; +import org.jetbrains.jps.model.library.sdk.JpsSdkType; +import org.jetbrains.jps.model.module.JpsDependenciesList; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleSourceRoot; +import org.jetbrains.jps.model.serialization.JpsMacroExpander; +import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; + +import java.util.List; +import java.util.Map; + +/** +* User: anna +* Date: 11/8/12 +*/ +class JpsIdeaSpecificSettings extends AbstractIdeaSpecificSettings<JpsModule, String, JpsSdkType<?>> { + private JpsMacroExpander myExpander; + + JpsIdeaSpecificSettings(JpsMacroExpander expander) { + myExpander = expander; + } + + @Override + protected void readLibraryLevels(Element root, Map<String, String> levels) { + final Element levelsElement = root.getChild("levels"); + if (levelsElement != null) { + for (Object child : levelsElement.getChildren("level")) { + final Element element = (Element)child; + final String libName = element.getAttributeValue("name"); + final String libLevel = element.getAttributeValue("value"); + if (libName != null && libLevel != null) { + levels.put(libName, libLevel); + } + } + } + } + + @Override + protected String[] getEntries(JpsModule model) { + final List<String> urls = model.getContentRootsList().getUrls(); + return ArrayUtil.toStringArray(urls); + } + + @Override + protected String createContentEntry(JpsModule model, String url) { + model.getContentRootsList().addUrl(url); + return url; + } + + @Override + protected void setupLibraryRoots(Element root, JpsModule model) {} + + @Override + protected void setupJdk(Element root, JpsModule model, @Nullable JpsSdkType<?> projectSdkType) { + final String inheritJdk = root.getAttributeValue("inheritJdk"); + final JpsDependenciesList dependenciesList = model.getDependenciesList(); + if (inheritJdk != null && Boolean.parseBoolean(inheritJdk)) { + dependenciesList.addSdkDependency(projectSdkType != null ? projectSdkType : JpsJavaSdkType.INSTANCE); + } + else { + final String jdkName = root.getAttributeValue("jdk"); + if (jdkName != null) { + String jdkType = root.getAttributeValue("jdk_type"); + JpsSdkType<?> sdkType = null; + if (jdkType != null) { + sdkType = JpsSdkTableSerializer.getSdkType(jdkType); + } + if (sdkType == null) { + sdkType = JpsJavaSdkType.INSTANCE; + } + dependenciesList.addSdkDependency(sdkType); + JpsSdkTableSerializer.setSdkReference(model.getSdkReferencesTable(), jdkName, sdkType); + if (sdkType instanceof JpsJavaSdkTypeWrapper) { + dependenciesList.addSdkDependency(JpsJavaSdkType.INSTANCE); + } + } + } + } + + @Override + protected void setupCompilerOutputs(Element root, JpsModule model) { + final JpsJavaModuleExtension extension = getService().getOrCreateModuleExtension(model); + final Element testOutputElement = root.getChild(IdeaXml.OUTPUT_TEST_TAG); + if (testOutputElement != null) { + extension.setTestOutputUrl(testOutputElement.getAttributeValue(IdeaXml.URL_ATTR)); + } + + final String inheritedOutput = root.getAttributeValue(IdeaXml.INHERIT_COMPILER_OUTPUT_ATTR); + if (inheritedOutput != null && Boolean.valueOf(inheritedOutput).booleanValue()) { + extension.setInheritOutput(true); + } + extension.setExcludeOutput(root.getChild(IdeaXml.EXCLUDE_OUTPUT_TAG) != null); + } + + @Override + protected void readLanguageLevel(Element root, JpsModule model) throws InvalidDataException {} + + @Override + protected void expandElement(Element root, JpsModule model) { + myExpander.substitute(root, SystemInfo.isFileSystemCaseSensitive); + } + + @Override + protected void overrideModulesScopes(Element root, JpsModule model) {} + + @Override + public void readContentEntry(Element root, String contentUrl, JpsModule model) { + for (Object o : root.getChildren(IdeaXml.TEST_FOLDER_TAG)) { + final String url = ((Element)o).getAttributeValue(IdeaXml.URL_ATTR); + JpsModuleSourceRoot folderToBeTest = null; + for (JpsModuleSourceRoot folder : model.getSourceRoots()) { + if (Comparing.strEqual(folder.getUrl(), url)) { + folderToBeTest = folder; + break; + } + } + if (folderToBeTest != null) { + model.removeSourceRoot(folderToBeTest.getUrl(), JavaSourceRootType.SOURCE); + } + model.addSourceRoot(url, JavaSourceRootType.TEST_SOURCE); + } + } + + private static JpsJavaExtensionService getService() { + return JpsJavaExtensionService.getInstance(); + } +} |