mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix IDEA-133542 Eclipse integration: external change or .classpath or .eml does not suggest to reload project (regression)
This commit is contained in:
+1
-2
@@ -22,7 +22,6 @@ package com.intellij.openapi.roots;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -78,7 +77,7 @@ public class LanguageLevelModuleExtensionImpl extends ModuleExtension<LanguageL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(final Element element) throws WriteExternalException {
|
||||
public void writeExternal(final Element element) {
|
||||
if (myLanguageLevel != null) {
|
||||
element.setAttribute(LANGUAGE_LEVEL_ELEMENT_NAME, myLanguageLevel.toString());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -157,9 +157,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx
|
||||
|
||||
// [dsl] we get here if either old file didn't exist or renaming failed
|
||||
final File oldFile = new File(getModuleFilePath());
|
||||
final File parentFile = oldFile.getParentFile();
|
||||
|
||||
final File newFile = new File(parentFile, newName + ModuleFileType.DOT_DEFAULT_EXTENSION);
|
||||
final File newFile = new File(oldFile.getParentFile(), newName + ModuleFileType.DOT_DEFAULT_EXTENSION);
|
||||
getStateStore().setModuleFilePath(newFile.getCanonicalPath());
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
+72
-78
@@ -16,16 +16,16 @@
|
||||
package com.intellij.openapi.roots.impl.storage;
|
||||
|
||||
import com.intellij.application.options.PathMacrosCollector;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.components.impl.stores.IModuleStore;
|
||||
import com.intellij.openapi.components.impl.stores.StateStorageBase;
|
||||
import com.intellij.openapi.components.impl.stores.StorageDataBase;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ModuleRootModel;
|
||||
import com.intellij.openapi.roots.impl.ModuleRootManagerImpl;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.roots.impl.ModuleRootManagerImpl.ModuleRootManagerState;
|
||||
import com.intellij.openapi.roots.impl.RootModelImpl;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -41,28 +41,26 @@ import org.jetbrains.jps.model.serialization.JpsProjectLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ClasspathStorage implements StateStorage {
|
||||
public class ClasspathStorage extends StateStorageBase<ClasspathStorage.MyStorageData> {
|
||||
@NonNls public static final String SPECIAL_STORAGE = "special";
|
||||
|
||||
@NonNls public static final String CLASSPATH_DIR_OPTION = JpsProjectLoader.CLASSPATH_DIR_ATTRIBUTE;
|
||||
|
||||
private final ClasspathStorageProvider.ClasspathConverter myConverter;
|
||||
private final TrackingPathMacroSubstitutor myTrackingPathMacroSubstitutor;
|
||||
|
||||
public ClasspathStorage(@NotNull Module module, @NotNull IModuleStore moduleStore) {
|
||||
super(moduleStore.getStateStorageManager().getMacroSubstitutor());
|
||||
|
||||
ClasspathStorageProvider provider = getProvider(ClassPathStorageUtil.getStorageType(module));
|
||||
assert provider != null;
|
||||
myConverter = provider.createConverter(module);
|
||||
assert myConverter != null;
|
||||
|
||||
myTrackingPathMacroSubstitutor = moduleStore.getStateStorageManager().getMacroSubstitutor();
|
||||
|
||||
VirtualFileTracker virtualFileTracker = ServiceManager.getService(VirtualFileTracker.class);
|
||||
if (virtualFileTracker != null) {
|
||||
List<String> urls = myConverter.getFileSet().getFileUrls();
|
||||
List<String> urls = myConverter.getFileUrls();
|
||||
for (String url : urls) {
|
||||
final Listener listener = module.getProject().getMessageBus().syncPublisher(PROJECT_STORAGE_TOPIC);
|
||||
virtualFileTracker.addTracker(url, new VirtualFileAdapter() {
|
||||
@@ -75,19 +73,51 @@ public class ClasspathStorage implements StateStorage {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T getState(final Object component, @NotNull String componentName, @NotNull Class<T> stateClass, @Nullable T mergeInto) {
|
||||
assert component instanceof ModuleRootManager;
|
||||
assert componentName.equals("NewModuleRootManager");
|
||||
assert stateClass == ModuleRootManagerImpl.ModuleRootManagerState.class;
|
||||
@Override
|
||||
protected <S> S deserializeState(@Nullable Element serializedState, @NotNull Class<S> stateClass, @Nullable S mergeInto) {
|
||||
if (serializedState == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ModuleRootManagerState state = new ModuleRootManagerState();
|
||||
state.readExternal(serializedState);
|
||||
//noinspection unchecked
|
||||
return (S)state;
|
||||
}
|
||||
|
||||
static class MyStorageData extends StorageDataBase {
|
||||
private boolean loaded;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getComponentNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasState(@NotNull String componentName) {
|
||||
return !loaded;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Element getStateAndArchive(@NotNull MyStorageData storageData, Object component, @NotNull String componentName) {
|
||||
if (storageData.loaded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Element element = new Element("component");
|
||||
try {
|
||||
Element element = new Element("component");
|
||||
ModifiableRootModel model = null;
|
||||
try {
|
||||
model = ((ModuleRootManagerImpl)component).getModifiableModel();
|
||||
myConverter.getClasspath(model, element);
|
||||
myConverter.readClasspath(model);
|
||||
((RootModelImpl)model).writeExternal(element);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
finally {
|
||||
if (model != null) {
|
||||
@@ -95,40 +125,43 @@ public class ClasspathStorage implements StateStorage {
|
||||
}
|
||||
}
|
||||
|
||||
myTrackingPathMacroSubstitutor.expandPaths(element);
|
||||
myTrackingPathMacroSubstitutor.addUnknownMacros(componentName, PathMacrosCollector.getMacroNames(element));
|
||||
|
||||
ModuleRootManagerImpl.ModuleRootManagerState moduleRootManagerState = new ModuleRootManagerImpl.ModuleRootManagerState();
|
||||
moduleRootManagerState.readExternal(element);
|
||||
//noinspection unchecked
|
||||
return (T)moduleRootManagerState;
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
throw new StateStorageException(e.getMessage());
|
||||
if (myPathMacroSubstitutor != null) {
|
||||
myPathMacroSubstitutor.expandPaths(element);
|
||||
myPathMacroSubstitutor.addUnknownMacros("NewModuleRootManager", PathMacrosCollector.getMacroNames(element));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
storageData.loaded = true;
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasState(@Nullable final Object component, @NotNull final String componentName, final Class<?> aClass, final boolean reloadData) {
|
||||
return true;
|
||||
protected MyStorageData loadData() {
|
||||
return new MyStorageData();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ExternalizationSession startExternalization() {
|
||||
return new ClasspathSaveSession();
|
||||
return myConverter.startExternalization();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void analyzeExternalChangesAndUpdateIfNeed(@NotNull Collection<VirtualFile> changedFiles, @NotNull Set<String> componentNames) {
|
||||
// if some file changed, so, changed
|
||||
componentNames.add("NewModuleRootManager");
|
||||
myStorageData.loaded = false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClasspathStorageProvider getProvider(@NotNull String type) {
|
||||
if (type.equals(ClassPathStorageUtil.DEFAULT_STORAGE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (ClasspathStorageProvider provider : ClasspathStorageProvider.EXTENSION_POINT_NAME.getExtensions()) {
|
||||
if (type.equals(provider.getID())) {
|
||||
return provider;
|
||||
@@ -145,7 +178,7 @@ public class ClasspathStorage implements StateStorage {
|
||||
@NotNull
|
||||
public static String getStorageRootFromOptions(@NotNull Module module) {
|
||||
String moduleRoot = getModuleDir(module);
|
||||
String storageRef = module.getOptionValue(CLASSPATH_DIR_OPTION);
|
||||
String storageRef = module.getOptionValue(JpsProjectLoader.CLASSPATH_DIR_ATTRIBUTE);
|
||||
if (storageRef == null) {
|
||||
return moduleRoot;
|
||||
}
|
||||
@@ -168,16 +201,16 @@ public class ClasspathStorage implements StateStorage {
|
||||
|
||||
provider = getProvider(storageId);
|
||||
if (provider == null) {
|
||||
module.clearOption(ClassPathStorageUtil.CLASSPATH_OPTION);
|
||||
module.clearOption(CLASSPATH_DIR_OPTION);
|
||||
module.clearOption(JpsProjectLoader.CLASSPATH_ATTRIBUTE);
|
||||
module.clearOption(JpsProjectLoader.CLASSPATH_DIR_ATTRIBUTE);
|
||||
}
|
||||
else {
|
||||
module.setOption(ClassPathStorageUtil.CLASSPATH_OPTION, storageId);
|
||||
module.setOption(CLASSPATH_DIR_OPTION, provider.getContentRoot(model));
|
||||
module.setOption(JpsProjectLoader.CLASSPATH_ATTRIBUTE, storageId);
|
||||
module.setOption(JpsProjectLoader.CLASSPATH_DIR_ATTRIBUTE, provider.getContentRoot(model));
|
||||
}
|
||||
}
|
||||
|
||||
public static void moduleRenamed(Module module, String newName) {
|
||||
public static void moduleRenamed(@NotNull Module module, @NotNull String newName) {
|
||||
ClasspathStorageProvider provider = getProvider(ClassPathStorageUtil.getStorageType(module));
|
||||
if (provider != null) {
|
||||
provider.moduleRenamed(module, newName);
|
||||
@@ -190,43 +223,4 @@ public class ClasspathStorage implements StateStorage {
|
||||
provider.modulePathChanged(module, path);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ClasspathSaveSession implements ExternalizationSession, SaveSession {
|
||||
@Override
|
||||
public void setState(@NotNull Object component, @NotNull String componentName, @NotNull Object state, Storage storageSpec) {
|
||||
assert component instanceof ModuleRootManager;
|
||||
assert componentName.equals("NewModuleRootManager");
|
||||
assert state.getClass() == ModuleRootManagerImpl.ModuleRootManagerState.class;
|
||||
|
||||
try {
|
||||
myConverter.setClasspath((ModuleRootManagerImpl)component);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SaveSession createSaveSession() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
myConverter.getFileSet().commit();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -15,19 +15,19 @@
|
||||
*/
|
||||
package com.intellij.openapi.roots.impl.storage;
|
||||
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootModel;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Kaznacheev
|
||||
@@ -46,20 +46,22 @@ public interface ClasspathStorageProvider {
|
||||
|
||||
void detach(@NotNull Module module);
|
||||
|
||||
void moduleRenamed(Module module, String newName);
|
||||
void moduleRenamed(@NotNull Module module, @NotNull String newName);
|
||||
|
||||
@Nullable
|
||||
ClasspathConverter createConverter(Module module);
|
||||
|
||||
String getContentRoot(ModuleRootModel model);
|
||||
String getContentRoot(@NotNull ModuleRootModel model);
|
||||
|
||||
void modulePathChanged(Module module, String path);
|
||||
|
||||
interface ClasspathConverter {
|
||||
FileSet getFileSet();
|
||||
@NotNull
|
||||
List<String> getFileUrls();
|
||||
|
||||
void getClasspath(@NotNull ModifiableRootModel model, @NotNull Element element) throws IOException;
|
||||
@NotNull
|
||||
StateStorage.ExternalizationSession startExternalization();
|
||||
|
||||
void setClasspath(ModuleRootModel model) throws IOException, WriteExternalException;
|
||||
void readClasspath(@NotNull ModifiableRootModel model) throws IOException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.intellij.openapi.roots.impl.storage;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface FileSet {
|
||||
@NotNull
|
||||
List<String> getFileUrls();
|
||||
|
||||
boolean hasChanged();
|
||||
|
||||
void commit() throws IOException;
|
||||
}
|
||||
+16
-2
@@ -32,9 +32,11 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.lang.CompoundRuntimeException;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.xmlb.JDOMXIncluder;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -172,13 +174,18 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
|
||||
protected void doSave(@Nullable List<SaveSession> saveSessions, @NotNull List<Pair<SaveSession, VirtualFile>> readonlyFiles) {
|
||||
if (saveSessions != null) {
|
||||
List<Throwable> errors = null;
|
||||
for (SaveSession session : saveSessions) {
|
||||
executeSave(session, readonlyFiles);
|
||||
errors = executeSave(session, readonlyFiles, errors);
|
||||
}
|
||||
if (errors != null) {
|
||||
throw new CompoundRuntimeException(errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void executeSave(@NotNull SaveSession session, @NotNull List<Pair<SaveSession, VirtualFile>> readonlyFiles) {
|
||||
@Nullable
|
||||
protected static List<Throwable> executeSave(@NotNull SaveSession session, @NotNull List<Pair<SaveSession, VirtualFile>> readonlyFiles, @Nullable List<Throwable> errors) {
|
||||
try {
|
||||
session.save();
|
||||
}
|
||||
@@ -186,6 +193,13 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
LOG.warn(e);
|
||||
readonlyFiles.add(Pair.create(session, e.getFile()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (errors == null) {
|
||||
errors = new SmartList<Throwable>();
|
||||
}
|
||||
errors.add(e);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private <T> void commitPersistentComponent(@NotNull PersistentStateComponent<T> component, @NotNull ExternalizationSession session, @Nullable String componentName) {
|
||||
|
||||
+8
-24
@@ -49,13 +49,12 @@ import java.util.Set;
|
||||
public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData> {
|
||||
private final File myDir;
|
||||
private volatile VirtualFile myVirtualFile;
|
||||
@SuppressWarnings("deprecation")
|
||||
private final StateSplitter mySplitter;
|
||||
|
||||
private DirectoryStorageData myStorageData;
|
||||
|
||||
public DirectoryBasedStorage(@Nullable TrackingPathMacroSubstitutor pathMacroSubstitutor,
|
||||
@NotNull String dir,
|
||||
@NotNull StateSplitter splitter,
|
||||
@SuppressWarnings("deprecation") @NotNull StateSplitter splitter,
|
||||
@NotNull Disposable parentDisposable,
|
||||
@Nullable final Listener listener) {
|
||||
super(pathMacroSubstitutor);
|
||||
@@ -98,7 +97,7 @@ public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData
|
||||
public void analyzeExternalChangesAndUpdateIfNeed(@NotNull Collection<VirtualFile> changedFiles, @NotNull Set<String> componentNames) {
|
||||
// todo reload only changed file, compute diff
|
||||
DirectoryStorageData oldData = myStorageData;
|
||||
DirectoryStorageData newData = loadState();
|
||||
DirectoryStorageData newData = loadData();
|
||||
myStorageData = newData;
|
||||
if (oldData == null) {
|
||||
componentNames.addAll(newData.getComponentNames());
|
||||
@@ -111,12 +110,13 @@ public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Element getStateAndArchive(@NotNull DirectoryStorageData storageData, @NotNull String componentName) {
|
||||
protected Element getStateAndArchive(@NotNull DirectoryStorageData storageData, Object component, @NotNull String componentName) {
|
||||
return storageData.getCompositeStateAndArchive(componentName, mySplitter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DirectoryStorageData loadState() {
|
||||
@Override
|
||||
protected DirectoryStorageData loadData() {
|
||||
DirectoryStorageData storageData = new DirectoryStorageData();
|
||||
storageData.loadFrom(getVirtualFile(), myPathMacroSubstitutor);
|
||||
return storageData;
|
||||
@@ -131,17 +131,6 @@ public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData
|
||||
return virtualFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected DirectoryStorageData getStorageData(boolean reloadData) {
|
||||
if (myStorageData != null && !reloadData) {
|
||||
return myStorageData;
|
||||
}
|
||||
|
||||
myStorageData = loadState();
|
||||
return myStorageData;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ExternalizationSession startExternalization() {
|
||||
@@ -231,16 +220,11 @@ public class DirectoryBasedStorage extends StateStorageBase<DirectoryStorageData
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
public void save() throws IOException {
|
||||
VirtualFile dir = storage.getVirtualFile();
|
||||
if (copiedStorageData.isEmpty()) {
|
||||
if (dir != null && dir.exists()) {
|
||||
try {
|
||||
StorageUtil.deleteFile(this, dir);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
StorageUtil.deleteFile(this, dir);
|
||||
}
|
||||
storage.myStorageData = copiedStorageData;
|
||||
return;
|
||||
|
||||
+8
-7
@@ -195,7 +195,7 @@ public class FileBasedStorage extends XmlElementStorage {
|
||||
|
||||
CharBuffer charBuffer = CharsetToolkit.UTF8_CHARSET.decode(ByteBuffer.wrap(file.contentsToByteArray()));
|
||||
myLineSeparator = StorageUtil.detectLineSeparators(charBuffer, isUseLfLineSeparatorByDefault() ? null : LineSeparator.LF);
|
||||
return JDOMUtil.loadDocument(charBuffer).getRootElement();
|
||||
return JDOMUtil.loadDocument(charBuffer).detachRootElement();
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
return processReadException(e);
|
||||
@@ -229,6 +229,7 @@ public class FileBasedStorage extends XmlElementStorage {
|
||||
super.setDefaultState(element);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void updatedFromStreamProvider(@NotNull Set<String> changedComponentNames, boolean deleted) {
|
||||
if (myRoamingType == RoamingType.DISABLED) {
|
||||
// storage roaming was changed to DISABLED, but settings repository has old state
|
||||
@@ -240,16 +241,16 @@ public class FileBasedStorage extends XmlElementStorage {
|
||||
if (newElement == null) {
|
||||
StorageUtil.deleteFile(myFile, this, myCachedVirtualFile);
|
||||
// if data was loaded, mark as changed all loaded components
|
||||
if (myLoadedData != null) {
|
||||
changedComponentNames.addAll(myLoadedData.getComponentNames());
|
||||
myLoadedData = null;
|
||||
if (myStorageData != null) {
|
||||
changedComponentNames.addAll(myStorageData.getComponentNames());
|
||||
myStorageData = null;
|
||||
}
|
||||
}
|
||||
else if (myLoadedData != null) {
|
||||
else if (myStorageData != null) {
|
||||
StorageData newStorageData = createStorageData();
|
||||
loadState(newStorageData, newElement);
|
||||
changedComponentNames.addAll(myLoadedData.getChangedComponentNames(newStorageData, myPathMacroSubstitutor));
|
||||
myLoadedData = newStorageData;
|
||||
changedComponentNames.addAll(myStorageData.getChangedComponentNames(newStorageData, myPathMacroSubstitutor));
|
||||
myStorageData = newStorageData;
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
|
||||
+7
-1
@@ -40,6 +40,7 @@ import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.util.PathUtilRt;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.lang.CompoundRuntimeException;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -472,8 +473,13 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
|
||||
else {
|
||||
List<Pair<SaveSession, VirtualFile>> oldList = new ArrayList<Pair<SaveSession, VirtualFile>>(readonlyFiles);
|
||||
readonlyFiles.clear();
|
||||
List<Throwable> errors = null;
|
||||
for (Pair<SaveSession, VirtualFile> entry : oldList) {
|
||||
executeSave(entry.first, readonlyFiles);
|
||||
errors = executeSave(entry.first, readonlyFiles, errors);
|
||||
}
|
||||
|
||||
if (errors != null) {
|
||||
throw new CompoundRuntimeException(errors);
|
||||
}
|
||||
|
||||
if (!readonlyFiles.isEmpty()) {
|
||||
|
||||
+20
-3
@@ -28,6 +28,8 @@ public abstract class StateStorageBase<T extends StorageDataBase> implements Sta
|
||||
private boolean mySavingDisabled = false;
|
||||
protected final TrackingPathMacroSubstitutor myPathMacroSubstitutor;
|
||||
|
||||
protected T myStorageData;
|
||||
|
||||
protected StateStorageBase(@Nullable TrackingPathMacroSubstitutor trackingPathMacroSubstitutor) {
|
||||
myPathMacroSubstitutor = trackingPathMacroSubstitutor;
|
||||
}
|
||||
@@ -35,11 +37,16 @@ public abstract class StateStorageBase<T extends StorageDataBase> implements Sta
|
||||
@Override
|
||||
@Nullable
|
||||
public final <S> S getState(Object component, @NotNull String componentName, @NotNull Class<S> stateClass, @Nullable S mergeInto) {
|
||||
return DefaultStateSerializer.deserializeState(getStateAndArchive(getStorageData(), componentName), stateClass, mergeInto);
|
||||
return deserializeState(getStateAndArchive(getStorageData(), component, componentName), stateClass, mergeInto);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract Element getStateAndArchive(@NotNull T storageData, @NotNull String componentName);
|
||||
protected <S> S deserializeState(@Nullable Element serializedState, @NotNull Class <S> stateClass, @Nullable S mergeInto) {
|
||||
return DefaultStateSerializer.deserializeState(serializedState, stateClass, mergeInto);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract Element getStateAndArchive(@NotNull T storageData, Object component, @NotNull String componentName);
|
||||
|
||||
@Override
|
||||
public final boolean hasState(@Nullable Object component, @NotNull String componentName, Class<?> aClass, boolean reloadData) {
|
||||
@@ -51,7 +58,17 @@ public abstract class StateStorageBase<T extends StorageDataBase> implements Sta
|
||||
return getStorageData(false);
|
||||
}
|
||||
|
||||
protected abstract T getStorageData(boolean reloadData);
|
||||
@NotNull
|
||||
protected final T getStorageData(boolean reload) {
|
||||
if (myStorageData != null && !reload) {
|
||||
return myStorageData;
|
||||
}
|
||||
|
||||
myStorageData = loadData();
|
||||
return myStorageData;
|
||||
}
|
||||
|
||||
protected abstract T loadData();
|
||||
|
||||
public final void disableSaving() {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -90,10 +90,12 @@ public final class StoreUtil {
|
||||
}
|
||||
|
||||
PluginId pluginId = PluginManagerCore.getPluginByClassName(componentClass.getName());
|
||||
if (pluginId != null) {
|
||||
if (pluginId == null) {
|
||||
throw new RuntimeException("No @State annotation found in " + componentClass);
|
||||
}
|
||||
else {
|
||||
throw new PluginException("No @State annotation found in " + componentClass, pluginId);
|
||||
}
|
||||
throw new RuntimeException("No @State annotation found in " + componentClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+17
-35
@@ -36,7 +36,6 @@ import java.util.Set;
|
||||
|
||||
public abstract class XmlElementStorage extends StateStorageBase<StorageData> {
|
||||
@NotNull protected final String myRootElementName;
|
||||
protected StorageData myLoadedData;
|
||||
protected final StreamProvider myStreamProvider;
|
||||
protected final String myFileSpec;
|
||||
protected boolean myBlockSavingTheContent = false;
|
||||
@@ -59,48 +58,36 @@ public abstract class XmlElementStorage extends StateStorageBase<StorageData> {
|
||||
@Nullable
|
||||
protected abstract Element loadLocalData();
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Element getStateAndArchive(@NotNull StorageData storageData, @NotNull String componentName) {
|
||||
protected Element getStateAndArchive(@NotNull StorageData storageData, Object component, @NotNull String componentName) {
|
||||
return storageData.getStateAndArchive(componentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected StorageData getStorageData(boolean reloadData) {
|
||||
if (myLoadedData != null && !reloadData) {
|
||||
return myLoadedData;
|
||||
}
|
||||
|
||||
myLoadedData = loadData(true);
|
||||
return myLoadedData;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected StorageData loadData(boolean useProvidersData) {
|
||||
protected StorageData loadData() {
|
||||
StorageData result = createStorageData();
|
||||
|
||||
if (useProvidersData && myStreamProvider != null && myStreamProvider.isEnabled()) {
|
||||
Element element;
|
||||
// we don't use local data if has stream provider
|
||||
if (myStreamProvider != null && myStreamProvider.isEnabled()) {
|
||||
try {
|
||||
Element element = loadDataFromStreamProvider();
|
||||
element = loadDataFromStreamProvider();
|
||||
if (element != null) {
|
||||
loadState(result, element);
|
||||
}
|
||||
|
||||
// we don't use local data if has stream provider
|
||||
return result;
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn(e);
|
||||
LOG.error(e);
|
||||
element = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
element = loadLocalData();
|
||||
}
|
||||
|
||||
Element element = loadLocalData();
|
||||
if (element != null) {
|
||||
loadState(result, element);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -120,8 +107,8 @@ public abstract class XmlElementStorage extends StateStorageBase<StorageData> {
|
||||
}
|
||||
|
||||
public void setDefaultState(@NotNull Element element) {
|
||||
myLoadedData = createStorageData();
|
||||
loadState(myLoadedData, element);
|
||||
myStorageData = createStorageData();
|
||||
loadState(myStorageData, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,7 +141,7 @@ public abstract class XmlElementStorage extends StateStorageBase<StorageData> {
|
||||
|
||||
@Override
|
||||
public void analyzeExternalChangesAndUpdateIfNeed(@NotNull Collection<VirtualFile> changedFiles, @NotNull Set<String> componentNames) {
|
||||
StorageData oldData = myLoadedData;
|
||||
StorageData oldData = myStorageData;
|
||||
StorageData newData = getStorageData(true);
|
||||
if (oldData == null) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
@@ -215,18 +202,13 @@ public abstract class XmlElementStorage extends StateStorageBase<StorageData> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void save() {
|
||||
public final void save() throws IOException {
|
||||
if (myBlockSavingTheContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
doSave(getElement(myCopiedStorageData, isCollapsePathsOnSave(), myNewLiveStates));
|
||||
myLoadedData = myCopiedStorageData;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
doSave(getElement(myCopiedStorageData, isCollapsePathsOnSave(), myNewLiveStates));
|
||||
myStorageData = myCopiedStorageData;
|
||||
}
|
||||
|
||||
// only because default project store hack
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.util.messages.Topic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -55,7 +56,7 @@ public interface StateStorage {
|
||||
}
|
||||
|
||||
interface SaveSession {
|
||||
void save();
|
||||
void save() throws IOException;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -18,7 +18,7 @@ package com.intellij.openapi.components;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
// todo remove?
|
||||
public interface XmlConfigurationMerger {
|
||||
@NotNull
|
||||
Element merge(Element original, Element mergeWith);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -16,14 +16,12 @@
|
||||
package com.intellij.core;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.StateStorageException;
|
||||
import com.intellij.openapi.components.impl.stores.StorageData;
|
||||
import com.intellij.openapi.module.impl.ModuleEx;
|
||||
import com.intellij.openapi.module.impl.ModuleManagerImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.impl.ModuleRootManagerImpl;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jdom.JDOMException;
|
||||
@@ -58,10 +56,7 @@ public class CoreModuleManager extends ModuleManagerImpl {
|
||||
((ModuleRootManagerImpl) ModuleRootManager.getInstance(module)).loadState(state);
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
throw new StateStorageException(e);
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
throw new StateStorageException(e);
|
||||
throw new IOException(e);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
+9
-10
@@ -15,31 +15,29 @@
|
||||
*/
|
||||
package com.intellij.openapi.components.impl.stores;
|
||||
|
||||
import com.intellij.openapi.components.StateStorageException;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.xmlb.XmlSerializationException;
|
||||
import com.intellij.util.xmlb.XmlSerializer;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@SuppressWarnings({"deprecation"})
|
||||
public class DefaultStateSerializer {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.DefaultStateSerializer");
|
||||
private static final Logger LOG = Logger.getInstance(DefaultStateSerializer.class);
|
||||
|
||||
private DefaultStateSerializer() {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Nullable
|
||||
public static <T> T deserializeState(@Nullable Element stateElement, Class <T> stateClass, @Nullable T mergeInto) throws XmlSerializationException {
|
||||
if (stateElement == null) return mergeInto;
|
||||
|
||||
if (stateClass.equals(Element.class)) {
|
||||
//assert mergeInto == null;
|
||||
public static <T> T deserializeState(@Nullable Element stateElement, Class <T> stateClass, @Nullable T mergeInto) {
|
||||
if (stateElement == null) {
|
||||
return mergeInto;
|
||||
}
|
||||
else if (stateClass == Element.class) {
|
||||
return (T)stateElement;
|
||||
}
|
||||
else if (JDOMExternalizable.class.isAssignableFrom(stateClass)) {
|
||||
@@ -47,13 +45,14 @@ public class DefaultStateSerializer {
|
||||
String elementText = JDOMUtil.writeElement(stateElement, "\n");
|
||||
LOG.error("State is " + stateClass.getName() + ", merge into is " + mergeInto.toString() + ", state element text is " + elementText);
|
||||
}
|
||||
final T t = ReflectionUtil.newInstance(stateClass);
|
||||
|
||||
T t = ReflectionUtil.newInstance(stateClass);
|
||||
try {
|
||||
((JDOMExternalizable)t).readExternal(stateElement);
|
||||
return t;
|
||||
}
|
||||
catch (InvalidDataException e) {
|
||||
throw new StateStorageException(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
else if (mergeInto == null) {
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -43,7 +43,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
final class StateMap {
|
||||
public final class StateMap {
|
||||
private static final Logger LOG = Logger.getInstance(StateMap.class);
|
||||
|
||||
private static final Format XML_FORMAT = Format.getRawFormat().
|
||||
@@ -178,7 +178,7 @@ final class StateMap {
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return ArrayUtil.realloc(byteOut.getInternalBuffer(), byteOut.size());
|
||||
}
|
||||
|
||||
+7
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -18,10 +18,7 @@ package com.intellij.openapi.components.impl.stores;
|
||||
import com.intellij.application.options.PathMacrosCollector;
|
||||
import com.intellij.openapi.components.PathMacroSubstitutor;
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
|
||||
import com.intellij.openapi.components.XmlConfigurationMerger;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.ExtensionPoint;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -29,7 +26,6 @@ import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.containers.StringInterner;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -39,13 +35,17 @@ import static com.intellij.openapi.components.impl.stores.StateMap.getNewByteIfD
|
||||
|
||||
public class StorageData extends StorageDataBase {
|
||||
private static final Logger LOG = Logger.getInstance(StorageData.class);
|
||||
@NonNls public static final String COMPONENT = "component";
|
||||
@NonNls public static final String NAME = "name";
|
||||
public static final String COMPONENT = "component";
|
||||
public static final String NAME = "name";
|
||||
|
||||
private final StateMap myStates;
|
||||
|
||||
protected final String myRootElementName;
|
||||
|
||||
public StorageData() {
|
||||
this(COMPONENT);
|
||||
}
|
||||
|
||||
public StorageData(@NotNull String rootElementName) {
|
||||
myStates = new StateMap();
|
||||
myRootElementName = rootElementName;
|
||||
@@ -80,11 +80,6 @@ public class StorageData extends StorageDataBase {
|
||||
JDOMUtil.internElement(element, interner);
|
||||
}
|
||||
|
||||
Object serverElement = myStates.get(name);
|
||||
if (serverElement != null) {
|
||||
element = mergeElements(name, element, (Element)serverElement);
|
||||
}
|
||||
|
||||
myStates.put(name, element);
|
||||
|
||||
if (pathMacroSubstitutor instanceof TrackingPathMacroSubstitutor) {
|
||||
@@ -106,17 +101,6 @@ public class StorageData extends StorageDataBase {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Element mergeElements(@NotNull String name, @NotNull Element localElement, @NotNull Element serverElement) {
|
||||
ExtensionPoint<XmlConfigurationMerger> point = Extensions.getRootArea().getExtensionPoint("com.intellij.componentConfigurationMerger");
|
||||
for (XmlConfigurationMerger merger : point.getExtensions()) {
|
||||
if (merger.getComponentName().equals(name)) {
|
||||
return merger.merge(serverElement, localElement);
|
||||
}
|
||||
}
|
||||
return serverElement;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Element save(@NotNull Map<String, Element> newLiveStates) {
|
||||
if (myStates.isEmpty()) {
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -368,17 +368,17 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo
|
||||
|
||||
public static class ModuleRootManagerState implements JDOMExternalizable {
|
||||
private RootModelImpl myRootModel;
|
||||
private Element myRootModelElement = null;
|
||||
private Element myRootModelElement;
|
||||
|
||||
public ModuleRootManagerState() {
|
||||
}
|
||||
|
||||
public ModuleRootManagerState(final RootModelImpl rootModel) {
|
||||
public ModuleRootManagerState(RootModelImpl rootModel) {
|
||||
myRootModel = rootModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
public void readExternal(Element element) {
|
||||
myRootModelElement = element;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -22,7 +22,6 @@ import org.jetbrains.jps.model.serialization.JpsProjectLoader;
|
||||
|
||||
public class ClassPathStorageUtil {
|
||||
@NonNls public static final String DEFAULT_STORAGE = "default";
|
||||
@NonNls public static final String CLASSPATH_OPTION = JpsProjectLoader.CLASSPATH_ATTRIBUTE;
|
||||
|
||||
public static boolean isDefaultStorage(@NotNull Module module) {
|
||||
return getStorageType(module).equals(DEFAULT_STORAGE);
|
||||
@@ -30,7 +29,7 @@ public class ClassPathStorageUtil {
|
||||
|
||||
@NotNull
|
||||
public static String getStorageType(@NotNull Module module) {
|
||||
String id = module.getOptionValue(CLASSPATH_OPTION);
|
||||
String id = module.getOptionValue(JpsProjectLoader.CLASSPATH_ATTRIBUTE);
|
||||
return id == null ? DEFAULT_STORAGE : id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -186,37 +186,23 @@ public class JDOMUtil {
|
||||
}
|
||||
|
||||
public static void internElement(@NotNull Element element, @NotNull StringInterner interner) {
|
||||
element.setName(intern(interner, element.getName()));
|
||||
element.setName(interner.intern(element.getName()));
|
||||
|
||||
for (Attribute attr : element.getAttributes()) {
|
||||
attr.setName(intern(interner, attr.getName()));
|
||||
attr.setValue(intern(interner, attr.getValue()));
|
||||
attr.setName(interner.intern(attr.getName()));
|
||||
attr.setValue(interner.intern(attr.getValue()));
|
||||
}
|
||||
|
||||
for (Content o : element.getContent()) {
|
||||
if (o instanceof Element) {
|
||||
Element e = (Element)o;
|
||||
internElement(e, interner);
|
||||
internElement((Element)o, interner);
|
||||
}
|
||||
else if (o instanceof Text) {
|
||||
Text text = (Text)o;
|
||||
text.setText(intern(interner, text.getText()));
|
||||
}
|
||||
else if (o instanceof Comment) {
|
||||
Comment comment = (Comment)o;
|
||||
comment.setText(intern(interner, comment.getText()));
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Wrong node: " + o);
|
||||
((Text)o).setText(interner.intern(o.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String intern(@NotNull final StringInterner interner, @NotNull final String s) {
|
||||
return interner.intern(s);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String legalizeText(@NotNull String str) {
|
||||
return legalizeChars(str).toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.util.lang;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,10 +27,10 @@ import java.util.List;
|
||||
public class CompoundRuntimeException extends RuntimeException {
|
||||
private final List<Throwable> myThrowables;
|
||||
|
||||
|
||||
public CompoundRuntimeException(final List<Throwable> throwables) {
|
||||
public CompoundRuntimeException(@NotNull List<Throwable> throwables) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
super("Several Exceptions occured", throwables.get(0));
|
||||
super("Several Exceptions occurred", throwables.get(0));
|
||||
|
||||
myThrowables = throwables;
|
||||
}
|
||||
|
||||
@@ -52,10 +51,15 @@ public class CompoundRuntimeException extends RuntimeException {
|
||||
}
|
||||
|
||||
public static void doThrow(@NotNull List<Throwable> throwables) {
|
||||
if (throwables.size()== 1) {
|
||||
if (throwables.size() == 1) {
|
||||
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
|
||||
Throwable throwable = throwables.get(0);
|
||||
if (throwable instanceof RuntimeException) throw (RuntimeException)throwable;
|
||||
if (throwable instanceof Error) throw (Error)throwable;
|
||||
if (throwable instanceof RuntimeException) {
|
||||
throw (RuntimeException)throwable;
|
||||
}
|
||||
if (throwable instanceof Error) {
|
||||
throw (Error)throwable;
|
||||
}
|
||||
}
|
||||
throw new CompoundRuntimeException(throwables);
|
||||
}
|
||||
|
||||
@@ -37,35 +37,42 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
@Nullable protected final List<String> myCurrentRoots;
|
||||
@Nullable protected final Set<String> myModuleNames;
|
||||
|
||||
public AbstractEclipseClasspathReader(final String rootPath,
|
||||
@Nullable List<String> currentRoots, @Nullable Set<String> moduleNames) {
|
||||
public AbstractEclipseClasspathReader(@NotNull String rootPath, @Nullable List<String> currentRoots, @Nullable Set<String> moduleNames) {
|
||||
myRootPath = FileUtil.toSystemIndependentName(rootPath);
|
||||
myCurrentRoots = currentRoots;
|
||||
myModuleNames = moduleNames;
|
||||
}
|
||||
|
||||
protected abstract String prepareValidUrlInsideJar(String url);
|
||||
|
||||
protected abstract void addNamedLibrary(T rootModel,
|
||||
Collection<String> unknownLibraries,
|
||||
boolean exported,
|
||||
String name,
|
||||
boolean applicationLevel);
|
||||
|
||||
protected abstract void addInvalidModuleEntry(T rootModel, boolean exported, String moduleName);
|
||||
|
||||
protected abstract void setUpModuleJdk(T rootModel,
|
||||
Collection<String> unknownJdks,
|
||||
EclipseModuleManager eclipseModuleManager,
|
||||
String jdkName);
|
||||
|
||||
public abstract void setupOutput(T rootModel, String path);
|
||||
|
||||
protected abstract void addSourceFolder(T rootModel, String srcUrl, boolean testFolder);
|
||||
|
||||
protected abstract void addSourceFolderToCurrentContentRoot(T rootModel, String srcUrl, boolean testFolder);
|
||||
|
||||
protected abstract void addJUnitDefaultLib(T rootModel, String junitName, ExpandMacroToPathMap macroMap);
|
||||
|
||||
protected abstract void addModuleLibrary(T rootModel,
|
||||
Element element,
|
||||
boolean exported,
|
||||
String libName,
|
||||
String url,
|
||||
String srcUrl, ExpandMacroToPathMap macroMap);
|
||||
|
||||
protected abstract String expandEclipsePath2Url(T rootModel, String path);
|
||||
|
||||
protected abstract Set<String> getDefinedCons();
|
||||
@@ -77,9 +84,9 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
Collection<String> unknownJdks,
|
||||
Set<String> refsToModules,
|
||||
final String testPattern,
|
||||
Element element, int idx,
|
||||
final EclipseModuleManager eclipseModuleManager,
|
||||
final ExpandMacroToPathMap macroMap,
|
||||
Element element, int index,
|
||||
@Nullable EclipseModuleManager eclipseModuleManager,
|
||||
final ExpandMacroToPathMap macroMap,
|
||||
final Set<String> libs) throws ConversionException {
|
||||
String kind = element.getAttributeValue(EclipseXml.KIND_ATTR);
|
||||
if (kind == null) {
|
||||
@@ -111,26 +118,33 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
catch (PatternSyntaxException e) {
|
||||
isTestFolder = false;
|
||||
}
|
||||
final String linked = expandLinkedResourcesPath(macroMap, path);
|
||||
if (linked != null) {
|
||||
srcUrl = prepareValidUrlInsideJar(pathToUrl(linked));
|
||||
eclipseModuleManager.registerEclipseLinkedSrcVarPath(srcUrl, path);
|
||||
addSourceFolder(rootModel, srcUrl, isTestFolder);
|
||||
}
|
||||
else {
|
||||
String linked = expandLinkedResourcesPath(macroMap, path);
|
||||
if (linked == null) {
|
||||
addSourceFolderToCurrentContentRoot(rootModel, srcUrl, isTestFolder);
|
||||
}
|
||||
eclipseModuleManager.setExpectedModuleSourcePlace(rearrange(rootModel));
|
||||
eclipseModuleManager.registerSrcPlace(srcUrl, idx);
|
||||
else {
|
||||
srcUrl = prepareValidUrlInsideJar(pathToUrl(linked));
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseLinkedSrcVarPath(srcUrl, path);
|
||||
}
|
||||
addSourceFolder(rootModel, srcUrl, isTestFolder);
|
||||
}
|
||||
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.setExpectedModuleSourcePlace(rearrange(rootModel));
|
||||
eclipseModuleManager.registerSrcPlace(srcUrl, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (kind.equals(EclipseXml.OUTPUT_KIND)) {
|
||||
String output = myRootPath + "/" + path;
|
||||
final String linked = expandLinkedResourcesPath(macroMap, path);
|
||||
String linked = expandLinkedResourcesPath(macroMap, path);
|
||||
if (linked != null) {
|
||||
output = linked;
|
||||
eclipseModuleManager.registerEclipseLinkedVarPath(pathToUrl(output), path);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseLinkedVarPath(pathToUrl(output), path);
|
||||
}
|
||||
}
|
||||
setupOutput(rootModel, output);
|
||||
}
|
||||
@@ -138,18 +152,21 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
else if (kind.equals(EclipseXml.LIB_KIND)) {
|
||||
final String libName = getPresentableName(path, libs);
|
||||
|
||||
|
||||
final String linked = expandLinkedResourcesPath(macroMap, path);
|
||||
final String url;
|
||||
String linked = expandLinkedResourcesPath(macroMap, path);
|
||||
String url;
|
||||
if (linked != null) {
|
||||
url = prepareValidUrlInsideJar(pathToUrl(linked));
|
||||
eclipseModuleManager.registerEclipseLinkedVarPath(url, path);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseLinkedVarPath(url, path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
url = expandEclipsePath2Url(rootModel, path);
|
||||
}
|
||||
|
||||
eclipseModuleManager.registerEclipseLibUrl(url);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseLibUrl(url);
|
||||
}
|
||||
|
||||
final String sourcePath = element.getAttributeValue(EclipseXml.SOURCEPATH_ATTR);
|
||||
String srcUrl = null;
|
||||
@@ -157,7 +174,9 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
final String linkedSrc = expandLinkedResourcesPath(macroMap, sourcePath);
|
||||
if (linkedSrc != null) {
|
||||
srcUrl = prepareValidUrlInsideJar(pathToUrl(linkedSrc));
|
||||
eclipseModuleManager.registerEclipseLinkedSrcVarPath(srcUrl, sourcePath);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseLinkedSrcVarPath(srcUrl, sourcePath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
srcUrl = expandEclipsePath2Url(rootModel, sourcePath);
|
||||
@@ -175,13 +194,17 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
|
||||
final String libName = getPresentableName(path, libs);
|
||||
|
||||
final String url = eclipseVariabledPath2Url(macroMap, path, 0);
|
||||
eclipseModuleManager.registerEclipseVariablePath(url, path);
|
||||
String url = eclipseVariabledPath2Url(macroMap, path, 0);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseVariablePath(url, path);
|
||||
}
|
||||
final String srcPathAttr = element.getAttributeValue(EclipseXml.SOURCEPATH_ATTR);
|
||||
String srcUrl = null;
|
||||
if (srcPathAttr != null) {
|
||||
srcUrl = eclipseVariabledPath2Url(macroMap, srcPathAttr, srcVarStart(srcPathAttr));
|
||||
eclipseModuleManager.registerEclipseSrcVariablePath(srcUrl, srcPathAttr);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerEclipseSrcVariablePath(srcUrl, srcPathAttr);
|
||||
}
|
||||
}
|
||||
addModuleLibrary(rootModel, element, exported, libName, url, srcUrl, macroMap);
|
||||
}
|
||||
@@ -201,13 +224,19 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
else if (path.startsWith(EclipseXml.JUNIT_CONTAINER)) {
|
||||
final String junitName = IdeaXml.JUNIT + getPresentableName(path);
|
||||
addJUnitDefaultLib(rootModel, junitName, macroMap);
|
||||
} else {
|
||||
final Set<String> registeredCons = getDefinedCons();
|
||||
}
|
||||
else {
|
||||
Set<String> registeredCons = getDefinedCons();
|
||||
if (registeredCons.contains(path)) {
|
||||
eclipseModuleManager.registerCon(path);
|
||||
eclipseModuleManager.registerSrcPlace(path, idx);
|
||||
} else {
|
||||
eclipseModuleManager.registerUnknownCons(path);
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerCon(path);
|
||||
eclipseModuleManager.registerSrcPlace(path, index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (eclipseModuleManager != null) {
|
||||
eclipseModuleManager.registerUnknownCons(path);
|
||||
}
|
||||
addNamedLibrary(rootModel, new ArrayList<String>(), exported, path, true);
|
||||
}
|
||||
}
|
||||
@@ -244,7 +273,8 @@ public abstract class AbstractEclipseClasspathReader<T> {
|
||||
return var == null ? null : ("$" + var + "$" + (path == null ? "" : ("/" + path)));
|
||||
}
|
||||
|
||||
protected static String pathToUrl(String path) {
|
||||
@NotNull
|
||||
protected static String pathToUrl(@NotNull String path) {
|
||||
return "file://" + path;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,15 +15,11 @@
|
||||
*/
|
||||
package org.jetbrains.idea.eclipse;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 10/29/12
|
||||
*/
|
||||
public interface EclipseModuleManager {
|
||||
void setInvalidJdk(String invalidJdk);
|
||||
|
||||
@@ -56,7 +52,7 @@ public interface EclipseModuleManager {
|
||||
|
||||
void registerUnknownCons(String con);
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
Set<String> getUnknownCons();
|
||||
|
||||
boolean isForceConfigureJDK();
|
||||
@@ -73,106 +69,5 @@ public interface EclipseModuleManager {
|
||||
|
||||
void registerSrcPlace(String srcUrl, int placeIdx);
|
||||
|
||||
@Nullable
|
||||
Integer getSrcPlace(String srcUtl);
|
||||
|
||||
EclipseModuleManager EMPTY = new EclipseModuleManager() {
|
||||
@Override
|
||||
public void setInvalidJdk(String invalidJdk) {}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getInvalidJdk() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCon(String name) {}
|
||||
|
||||
@Override
|
||||
public String[] getUsedCons() {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEclipseVariablePath(String path, String var) {}
|
||||
|
||||
@Override
|
||||
public void registerEclipseSrcVariablePath(String path, String var) {}
|
||||
|
||||
@Override
|
||||
public void registerEclipseLinkedSrcVarPath(String path, String var) {}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getEclipseLinkedSrcVariablePath(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEclipseLinkedVarPath(String path, String var) {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getEclipseLinkedVarPath(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getEclipseVariablePath(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getEclipseSrcVariablePath(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerUnknownCons(String con) {}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<String> getUnknownCons() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceConfigureJDK() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForceConfigureJDK() {}
|
||||
|
||||
@Override
|
||||
public void registerEclipseLibUrl(String url) {}
|
||||
|
||||
@Override
|
||||
public boolean isEclipseLibUrl(String url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpectedModuleSourcePlace(int expectedModuleSourcePlace) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpectedModuleSourcePlace(int expectedPlace) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSrcPlace(String srcUrl, int placeIdx) {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer getSrcPlace(String srcUtl) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
int getSrcPlace(String srcUtl);
|
||||
}
|
||||
|
||||
+6
-3
@@ -29,7 +29,7 @@ import java.util.Map;
|
||||
* Date: 11/8/12
|
||||
*/
|
||||
public abstract class AbstractIdeaSpecificSettings<T, C, SdkType> {
|
||||
public void readIdeaSpecific(@NotNull Element root, T model, @Nullable SdkType projectSdkType, Map<String, String> levels) {
|
||||
public void readIdeaSpecific(@NotNull Element root, T model, @Nullable SdkType projectSdkType, @Nullable Map<String, String> levels) {
|
||||
expandElement(root, model);
|
||||
|
||||
readLanguageLevel(root, model);
|
||||
@@ -40,7 +40,9 @@ public abstract class AbstractIdeaSpecificSettings<T, C, SdkType> {
|
||||
setupJdk(root, model, projectSdkType);
|
||||
setupLibraryRoots(root, model);
|
||||
overrideModulesScopes(root, model);
|
||||
readLibraryLevels(root, levels);
|
||||
if (levels != null) {
|
||||
readLibraryLevels(root, levels);
|
||||
}
|
||||
}
|
||||
|
||||
public void initLevels(final Element root, T model, Map<String, String> levels) throws InvalidDataException {
|
||||
@@ -71,7 +73,8 @@ public abstract class AbstractIdeaSpecificSettings<T, C, SdkType> {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void readLibraryLevels(Element root, Map<String, String> levels);
|
||||
protected void readLibraryLevels(Element root, @NotNull Map<String, String> levels) {
|
||||
}
|
||||
|
||||
protected abstract C[] getEntries(T model);
|
||||
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ class JpsEclipseClasspathReader extends AbstractEclipseClasspathReader<JpsModule
|
||||
for (Object o : classpathElement.getChildren(EclipseXml.CLASSPATHENTRY_TAG)) {
|
||||
try {
|
||||
readClasspathEntry(model, new ArrayList<String>(), new ArrayList<String>(), new HashSet<String>(),
|
||||
testPattern, (Element)o, 0, EclipseModuleManager.EMPTY, expander.getExpandMacroMap(), libs);
|
||||
testPattern, (Element)o, 0, null, expander.getExpandMacroMap(), libs);
|
||||
}
|
||||
catch (ConversionException e) {
|
||||
throw new IOException(e);
|
||||
|
||||
+6
-8
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.IdeaXml;
|
||||
import org.jetbrains.idea.eclipse.conversion.AbstractIdeaSpecificSettings;
|
||||
@@ -33,7 +34,6 @@ import org.jetbrains.jps.model.serialization.JpsMacroExpander;
|
||||
import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -48,13 +48,12 @@ class JpsIdeaSpecificSettings extends AbstractIdeaSpecificSettings<JpsModule, St
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readLibraryLevels(Element root, Map<String, String> levels) {
|
||||
protected void readLibraryLevels(Element root, @NotNull 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");
|
||||
for (Element element : levelsElement.getChildren("level")) {
|
||||
String libName = element.getAttributeValue("name");
|
||||
String libLevel = element.getAttributeValue("value");
|
||||
if (libName != null && libLevel != null) {
|
||||
levels.put(libName, libLevel);
|
||||
}
|
||||
@@ -64,8 +63,7 @@ class JpsIdeaSpecificSettings extends AbstractIdeaSpecificSettings<JpsModule, St
|
||||
|
||||
@Override
|
||||
protected String[] getEntries(JpsModule model) {
|
||||
final List<String> urls = model.getContentRootsList().getUrls();
|
||||
return ArrayUtil.toStringArray(urls);
|
||||
return ArrayUtil.toStringArray(model.getContentRootsList().getUrls());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@ eclipse.import.action.convert=.iml will be created
|
||||
eclipse.import.action.link=.iml will be created and linked to .classpath
|
||||
eclipse.import.warning.undefinded.libraries=Imported project refers to unknown global libraries
|
||||
eclipse.import.count.undefined.libraries= ({0} more...)
|
||||
eclipse.import.converting=Converting Eclipse projects
|
||||
eclipse.import.converting=Converting Eclipse Projects
|
||||
eclipse.import.scanning=Scanning Eclipse projects
|
||||
eclipse.export.dialog.title=Export to Eclipse
|
||||
eclipse.export.operation=Export
|
||||
|
||||
@@ -15,52 +15,42 @@
|
||||
*/
|
||||
package org.jetbrains.idea.eclipse.config;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.impl.storage.FileSet;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.output.EclipseJDOMUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CachedXmlDocumentSet implements FileSet {
|
||||
protected final Map<String, String> nameToDir = new THashMap<String, String>();
|
||||
protected final Map<String, Element> savedContent = new THashMap<String, Element>();
|
||||
protected final Map<String, Element> modifiedContent = new THashMap<String, Element>();
|
||||
protected final Set<String> deletedContent = new THashSet<String>();
|
||||
private final Project project;
|
||||
public class CachedXmlDocumentSet {
|
||||
private final Map<String, String> nameToDir = new THashMap<String, String>();
|
||||
|
||||
public CachedXmlDocumentSet(@NotNull Project project) {
|
||||
this.project = project;
|
||||
}
|
||||
@Nullable
|
||||
public Element load(@NotNull String name, boolean refresh) throws IOException, JDOMException {
|
||||
assertKnownName(name);
|
||||
|
||||
@NotNull
|
||||
public Element read(@NotNull String name) throws IOException, JDOMException {
|
||||
return read(name, true);
|
||||
}
|
||||
VirtualFile file = getFile(name, refresh);
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Element read(@NotNull String name, final boolean refresh) throws IOException, JDOMException {
|
||||
return load(name, refresh).clone();
|
||||
}
|
||||
|
||||
public void write(Element element, String name) throws IOException {
|
||||
update(element.clone(), name);
|
||||
InputStream inputStream = file.getInputStream();
|
||||
try {
|
||||
return JDOMUtil.load(inputStream);
|
||||
}
|
||||
finally {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getParent(@NotNull String name) {
|
||||
@@ -75,18 +65,12 @@ public class CachedXmlDocumentSet implements FileSet {
|
||||
assert nameToDir.containsKey(name) : name;
|
||||
}
|
||||
|
||||
public boolean exists(String name) {
|
||||
assertKnownName(name);
|
||||
return !deletedContent.contains(name) && getFile(name) != null;
|
||||
public boolean exists(@NotNull String name) {
|
||||
return getFile(name, false) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected VirtualFile getFile(@NotNull String name) {
|
||||
return getFile(name, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected VirtualFile getFile(@NotNull String name, boolean refresh) {
|
||||
VirtualFile getFile(@NotNull String name, boolean refresh) {
|
||||
VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(new File(getParent(name), name));
|
||||
if (file != null && refresh) {
|
||||
file.refresh(false, true);
|
||||
@@ -98,53 +82,6 @@ public class CachedXmlDocumentSet implements FileSet {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private VirtualFile getOrCreateVFile(@NotNull String name) throws IOException {
|
||||
return StorageUtil.getOrCreateVirtualFile(this, new File(getParent(name), name));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Element load(@NotNull String name, boolean refresh) throws IOException, JDOMException {
|
||||
assertKnownName(name);
|
||||
|
||||
Element logical = modifiedContent.get(name);
|
||||
if (logical != null) {
|
||||
return logical;
|
||||
}
|
||||
|
||||
Element physical = savedContent.get(name);
|
||||
if (physical == null) {
|
||||
VirtualFile file = deletedContent.contains(name) ? null : getFile(name, refresh);
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream inputStream = file.getInputStream();
|
||||
try {
|
||||
physical = JDOMUtil.load(inputStream);
|
||||
}
|
||||
finally {
|
||||
inputStream.close();
|
||||
}
|
||||
savedContent.put(name, physical);
|
||||
}
|
||||
return physical;
|
||||
}
|
||||
|
||||
public void update(Element content, final String name) {
|
||||
assertKnownName(name);
|
||||
modifiedContent.put(name, content);
|
||||
deletedContent.remove(name);
|
||||
}
|
||||
|
||||
public void delete(String name) {
|
||||
modifiedContent.remove(name);
|
||||
savedContent.remove(name);
|
||||
deletedContent.add(name);
|
||||
//nameToDir.remove(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getFileUrls() {
|
||||
List<String> list = new ArrayList<String>(nameToDir.size());
|
||||
for (String name : nameToDir.keySet()) {
|
||||
@@ -152,60 +89,4 @@ public class CachedXmlDocumentSet implements FileSet {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public boolean hasChanged() {
|
||||
for (String key : modifiedContent.keySet()) {
|
||||
if (hasChanged(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !deletedContent.isEmpty();
|
||||
}
|
||||
|
||||
private boolean hasChanged(@NotNull String key) {
|
||||
Element content = modifiedContent.get(key);
|
||||
Element physical1 = content == null ? null : content;
|
||||
Element physical2 = savedContent.get(key);
|
||||
if (physical1 != null && physical2 != null) {
|
||||
return !JDOMUtil.areElementsEqual(physical1, physical2);
|
||||
}
|
||||
return physical1 != physical2;
|
||||
}
|
||||
|
||||
public void commit() throws IOException {
|
||||
for (String key : modifiedContent.keySet()) {
|
||||
if (hasChanged(key)) {
|
||||
Element content = modifiedContent.get(key);
|
||||
if (content != null) {
|
||||
Writer writer = new OutputStreamWriter(getOrCreateVFile(key).getOutputStream(this), CharsetToolkit.UTF8_CHARSET);
|
||||
try {
|
||||
EclipseJDOMUtil.output(content, writer, project);
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
savedContent.put(key, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (String deleted : deletedContent) {
|
||||
VirtualFile file = getFile(deleted);
|
||||
if (file != null) {
|
||||
try {
|
||||
file.delete(this);
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
deletedContent.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.idea.eclipse.config;
|
||||
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil;
|
||||
import com.intellij.openapi.editor.DocumentRunnable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.impl.ModuleRootManagerImpl;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.output.EclipseJDOMUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
import org.jetbrains.idea.eclipse.IdeaXml;
|
||||
import org.jetbrains.idea.eclipse.conversion.DotProjectFileHelper;
|
||||
import org.jetbrains.idea.eclipse.conversion.EclipseClasspathWriter;
|
||||
import org.jetbrains.idea.eclipse.conversion.IdeaSpecificSettings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
final class ClasspathSaveSession implements StateStorage.ExternalizationSession, StateStorage.SaveSession {
|
||||
private final Map<String, Element> modifiedContent = new THashMap<String, Element>();
|
||||
private final Set<String> deletedContent = new THashSet<String>();
|
||||
|
||||
private final Module module;
|
||||
|
||||
ClasspathSaveSession(@NotNull Module module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
private void update(@NotNull Element content, @NotNull String name) {
|
||||
modifiedContent.put(name, content);
|
||||
deletedContent.remove(name);
|
||||
}
|
||||
|
||||
void delete(@NotNull String name) {
|
||||
modifiedContent.remove(name);
|
||||
deletedContent.add(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(@NotNull Object component, @NotNull String componentName, @NotNull Object state, Storage storageSpec) {
|
||||
try {
|
||||
CachedXmlDocumentSet fileSet = EclipseClasspathStorageProvider.getFileCache(module);
|
||||
|
||||
Element oldClassPath;
|
||||
try {
|
||||
oldClassPath = fileSet.load(EclipseXml.CLASSPATH_FILE, true);
|
||||
}
|
||||
catch (Exception e) {
|
||||
EclipseClasspathWriter.LOG.warn(e);
|
||||
oldClassPath = null;
|
||||
}
|
||||
|
||||
ModuleRootManagerImpl moduleRootManager = (ModuleRootManagerImpl)component;
|
||||
if (oldClassPath != null || moduleRootManager.getSourceRoots().length > 0 || moduleRootManager.getOrderEntries().length > 2) {
|
||||
Element newClassPathElement = new EclipseClasspathWriter().writeClasspath(oldClassPath, moduleRootManager);
|
||||
if (oldClassPath == null || !JDOMUtil.areElementsEqual(newClassPathElement, oldClassPath)) {
|
||||
update(newClassPathElement, EclipseXml.CLASSPATH_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileSet.getFile(EclipseXml.PROJECT_FILE, true) == null) {
|
||||
DotProjectFileHelper.saveDotProjectFile(module, fileSet.getParent(EclipseXml.PROJECT_FILE));
|
||||
}
|
||||
|
||||
Element ideaSpecific = new Element(IdeaXml.COMPONENT_TAG);
|
||||
String emlFilename = moduleRootManager.getModule().getName() + EclipseXml.IDEA_SETTINGS_POSTFIX;
|
||||
if (IdeaSpecificSettings.writeIdeaSpecificClasspath(ideaSpecific, moduleRootManager)) {
|
||||
update(ideaSpecific, emlFilename);
|
||||
}
|
||||
else {
|
||||
delete(emlFilename);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StateStorage.SaveSession createSaveSession() {
|
||||
return modifiedContent.isEmpty() && deletedContent.isEmpty() ? null : this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
CachedXmlDocumentSet fileSet = EclipseClasspathStorageProvider.getFileCache(module);
|
||||
|
||||
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
|
||||
try {
|
||||
for (String key : modifiedContent.keySet()) {
|
||||
Element content = modifiedContent.get(key);
|
||||
Writer writer = new OutputStreamWriter(StorageUtil.getOrCreateVirtualFile(this, new File(fileSet.getParent(key), key)).getOutputStream(this), CharsetToolkit.UTF8_CHARSET);
|
||||
try {
|
||||
EclipseJDOMUtil.output(content, writer, module.getProject());
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (deletedContent.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String deleted : deletedContent) {
|
||||
VirtualFile file = fileSet.getFile(deleted, false);
|
||||
if (file != null) {
|
||||
try {
|
||||
file.delete(this);
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
deletedContent.clear();
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.idea.eclipse.config;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.impl.storage.ClasspathStorageProvider;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
import org.jetbrains.idea.eclipse.conversion.EclipseClasspathReader;
|
||||
import org.jetbrains.idea.eclipse.conversion.IdeaSpecificSettings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public final class EclipseClasspathConverter implements ClasspathStorageProvider.ClasspathConverter {
|
||||
private final Module module;
|
||||
|
||||
public EclipseClasspathConverter(@NotNull Module module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getFileUrls() {
|
||||
return getFileSet().getFileUrls();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ClasspathSaveSession startExternalization() {
|
||||
return new ClasspathSaveSession(module);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CachedXmlDocumentSet getFileSet() {
|
||||
return EclipseClasspathStorageProvider.getFileCache(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readClasspath(@NotNull ModifiableRootModel model) throws IOException {
|
||||
try {
|
||||
CachedXmlDocumentSet fileSet = getFileSet();
|
||||
String path = fileSet.getParent(EclipseXml.PROJECT_FILE);
|
||||
Element classpath = null;
|
||||
if (!fileSet.exists(EclipseXml.PROJECT_FILE)) {
|
||||
classpath = fileSet.load(EclipseXml.CLASSPATH_FILE, false);
|
||||
if (classpath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
path = fileSet.getParent(EclipseXml.CLASSPATH_FILE);
|
||||
}
|
||||
|
||||
EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, module.getProject(), null);
|
||||
classpathReader.init(model);
|
||||
|
||||
if (classpath == null) {
|
||||
classpath = fileSet.load(EclipseXml.CLASSPATH_FILE, false);
|
||||
}
|
||||
|
||||
if (classpath == null) {
|
||||
EclipseClasspathReader.setOutputUrl(model, path + "/bin");
|
||||
}
|
||||
else {
|
||||
classpathReader.readClasspath(model, classpath);
|
||||
}
|
||||
|
||||
Element eml = fileSet.load(model.getModule().getName() + EclipseXml.IDEA_SETTINGS_POSTFIX, false);
|
||||
if (eml == null) {
|
||||
model.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false);
|
||||
}
|
||||
else {
|
||||
new IdeaSpecificSettings().readIdeaSpecific(eml, model, null, null);
|
||||
}
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-129
@@ -15,39 +15,32 @@
|
||||
*/
|
||||
package org.jetbrains.idea.eclipse.config;
|
||||
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.editor.DocumentRunnable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.RootModelImpl;
|
||||
import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil;
|
||||
import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
|
||||
import com.intellij.openapi.roots.impl.storage.ClasspathStorageProvider;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.SmartList;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.ConversionException;
|
||||
import org.jetbrains.idea.eclipse.EclipseBundle;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
import org.jetbrains.idea.eclipse.IdeaXml;
|
||||
import org.jetbrains.idea.eclipse.conversion.*;
|
||||
import org.jetbrains.idea.eclipse.conversion.DotProjectFileHelper;
|
||||
import org.jetbrains.idea.eclipse.conversion.EPathUtil;
|
||||
import org.jetbrains.idea.eclipse.conversion.EclipseClasspathWriter;
|
||||
import org.jetbrains.jps.eclipse.model.JpsEclipseClasspathSerializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Kaznacheev
|
||||
@@ -114,10 +107,9 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentRoot(ModuleRootModel model) {
|
||||
final VirtualFile contentRoot = EPathUtil.getContentRoot(model);
|
||||
if (contentRoot != null) return contentRoot.getPath();
|
||||
return model.getContentRoots()[0].getPath();
|
||||
public String getContentRoot(@NotNull ModuleRootModel model) {
|
||||
VirtualFile contentRoot = EPathUtil.getContentRoot(model);
|
||||
return contentRoot == null ? model.getContentRoots()[0].getPath() : contentRoot.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,7 +125,7 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider
|
||||
EclipseModuleManagerImpl moduleManager = EclipseModuleManagerImpl.getInstance(module);
|
||||
CachedXmlDocumentSet fileCache = moduleManager != null ? moduleManager.getDocumentSet() : null;
|
||||
if (fileCache == null) {
|
||||
fileCache = new CachedXmlDocumentSet(module.getProject());
|
||||
fileCache = new CachedXmlDocumentSet();
|
||||
if (moduleManager != null) {
|
||||
moduleManager.setDocumentSet(fileCache);
|
||||
}
|
||||
@@ -148,121 +140,26 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleRenamed(final Module module, String newName) {
|
||||
if (ClassPathStorageUtil.getStorageType(module).equals(JpsEclipseClasspathSerializer.CLASSPATH_STORAGE_ID)) {
|
||||
try {
|
||||
String oldEmlName = module.getName() + EclipseXml.IDEA_SETTINGS_POSTFIX;
|
||||
String root = getFileCache(module).getParent(oldEmlName);
|
||||
File source = new File(root, oldEmlName);
|
||||
if (source.exists()) {
|
||||
File target = new File(root, newName + EclipseXml.IDEA_SETTINGS_POSTFIX);
|
||||
FileUtil.rename(source, target);
|
||||
LocalFileSystem.getInstance().refreshAndFindFileByIoFile(target);
|
||||
}
|
||||
CachedXmlDocumentSet fileCache = getFileCache(module);
|
||||
DotProjectFileHelper.saveDotProjectFile(module, fileCache.getParent(EclipseXml.PROJECT_FILE));
|
||||
fileCache.delete(oldEmlName);
|
||||
fileCache.register(newName + EclipseXml.IDEA_SETTINGS_POSTFIX, ClasspathStorage.getModuleDir(module));
|
||||
fileCache.load(newName + EclipseXml.IDEA_SETTINGS_POSTFIX, true);
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
catch (JDOMException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EclipseClasspathConverter implements ClasspathConverter {
|
||||
private final Module module;
|
||||
|
||||
public EclipseClasspathConverter(@NotNull Module module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedXmlDocumentSet getFileSet() {
|
||||
return getFileCache(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getClasspath(@NotNull ModifiableRootModel model, @NotNull Element element) throws IOException {
|
||||
try {
|
||||
CachedXmlDocumentSet documentSet = getFileSet();
|
||||
String path = documentSet.getParent(EclipseXml.PROJECT_FILE);
|
||||
if (!documentSet.exists(EclipseXml.PROJECT_FILE)) {
|
||||
if (!documentSet.exists(EclipseXml.CLASSPATH_FILE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
path = documentSet.getParent(EclipseXml.CLASSPATH_FILE);
|
||||
}
|
||||
|
||||
EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, module.getProject(), null);
|
||||
classpathReader.init(model);
|
||||
if (documentSet.exists(EclipseXml.CLASSPATH_FILE)) {
|
||||
classpathReader.readClasspath(model, new SmartList<String>(), new SmartList<String>(), new THashSet<String>(), null,
|
||||
documentSet.read(EclipseXml.CLASSPATH_FILE, false));
|
||||
}
|
||||
else {
|
||||
EclipseClasspathReader.setOutputUrl(model, path + "/bin");
|
||||
}
|
||||
String eml = model.getModule().getName() + EclipseXml.IDEA_SETTINGS_POSTFIX;
|
||||
if (documentSet.exists(eml)) {
|
||||
new IdeaSpecificSettings().readIdeaSpecific(documentSet.read(eml, false), model, null, new HashMap<String, String>());
|
||||
}
|
||||
else {
|
||||
model.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false);
|
||||
}
|
||||
|
||||
((RootModelImpl)model).writeExternal(element);
|
||||
}
|
||||
catch (WriteExternalException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClasspath(final ModuleRootModel model) throws IOException, WriteExternalException {
|
||||
try {
|
||||
final Element classpathElement = new Element(EclipseXml.CLASSPATH_TAG);
|
||||
final EclipseClasspathWriter classpathWriter = new EclipseClasspathWriter(model);
|
||||
final CachedXmlDocumentSet fileSet = getFileSet();
|
||||
|
||||
Element element;
|
||||
public void moduleRenamed(@NotNull Module module, @NotNull String newName) {
|
||||
try {
|
||||
CachedXmlDocumentSet fileSet = getFileCache(module);
|
||||
VirtualFile root = LocalFileSystem.getInstance().findFileByPath(ClasspathStorage.getModuleDir(module));
|
||||
VirtualFile source = root == null ? null : root.findChild(module.getName() + EclipseXml.IDEA_SETTINGS_POSTFIX);
|
||||
if (source != null && source.isValid()) {
|
||||
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
|
||||
try {
|
||||
element = fileSet.read(EclipseXml.CLASSPATH_FILE);
|
||||
source.rename(this, newName + EclipseXml.IDEA_SETTINGS_POSTFIX);
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
element = null;
|
||||
}
|
||||
|
||||
if (element != null || model.getSourceRoots().length > 0 || model.getOrderEntries().length > 2) {
|
||||
classpathWriter.writeClasspath(classpathElement, element);
|
||||
fileSet.write(classpathElement, EclipseXml.CLASSPATH_FILE);
|
||||
}
|
||||
|
||||
try {
|
||||
fileSet.read(EclipseXml.PROJECT_FILE);
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
DotProjectFileHelper.saveDotProjectFile(module, fileSet.getParent(EclipseXml.PROJECT_FILE));
|
||||
}
|
||||
|
||||
Element ideaSpecific = new Element(IdeaXml.COMPONENT_TAG);
|
||||
String emlFilename = model.getModule().getName() + EclipseXml.IDEA_SETTINGS_POSTFIX;
|
||||
if (IdeaSpecificSettings.writeIDEASpecificClasspath(ideaSpecific, model)) {
|
||||
fileSet.write(ideaSpecific, emlFilename);
|
||||
}
|
||||
else {
|
||||
fileSet.delete(emlFilename);
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
catch (ConversionException e) {
|
||||
throw new WriteExternalException(e.getMessage());
|
||||
}
|
||||
|
||||
DotProjectFileHelper.saveDotProjectFile(module, fileSet.getParent(EclipseXml.PROJECT_FILE));
|
||||
fileSet.register(newName + EclipseXml.IDEA_SETTINGS_POSTFIX, ClasspathStorage.getModuleDir(module));
|
||||
}
|
||||
catch (IOException e) {
|
||||
EclipseClasspathWriter.LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+86
-84
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.EclipseModuleManager;
|
||||
import org.jetbrains.jps.eclipse.model.JpsEclipseClasspathSerializer;
|
||||
@@ -53,7 +54,7 @@ public class EclipseModuleManagerImpl implements EclipseModuleManager, Persisten
|
||||
private final Map<String, String> myEclipseVariablePaths = new LinkedHashMap<String, String>();
|
||||
private final Set<String> myEclipseUrls = new LinkedHashSet<String>();
|
||||
private final Set<String> myUnknownCons = new LinkedHashSet<String>();
|
||||
private boolean myForceConfigureJDK = false;
|
||||
private boolean myForceConfigureJDK;
|
||||
@NonNls private static final String SRC_PREFIX = "src:";
|
||||
@NonNls private static final String SRC_LINK_PREFIX = "linksrc:";
|
||||
@NonNls private static final String LINK_PREFIX = "link:";
|
||||
@@ -70,6 +71,14 @@ public class EclipseModuleManagerImpl implements EclipseModuleManager, Persisten
|
||||
myModule = module;
|
||||
}
|
||||
|
||||
public static EclipseModuleManagerImpl getInstance(Module module) {
|
||||
return ModuleServiceManager.getService(module, EclipseModuleManagerImpl.class);
|
||||
}
|
||||
|
||||
public static boolean isEclipseStorage(@NotNull Module module) {
|
||||
return JpsEclipseClasspathSerializer.CLASSPATH_STORAGE_ID.equals(ClassPathStorageUtil.getStorageType(module));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInvalidJdk(String invalidJdk) {
|
||||
myInvalidJdk = invalidJdk;
|
||||
@@ -90,10 +99,6 @@ public class EclipseModuleManagerImpl implements EclipseModuleManager, Persisten
|
||||
return ArrayUtil.toStringArray(myKnownCons);
|
||||
}
|
||||
|
||||
public static EclipseModuleManagerImpl getInstance(Module module) {
|
||||
return ModuleServiceManager.getService(module, EclipseModuleManagerImpl.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CachedXmlDocumentSet getDocumentSet() {
|
||||
return myDocumentSet;
|
||||
@@ -148,6 +153,7 @@ public class EclipseModuleManagerImpl implements EclipseModuleManager, Persisten
|
||||
myUnknownCons.add(con);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getUnknownCons() {
|
||||
return myUnknownCons;
|
||||
@@ -176,93 +182,88 @@ public class EclipseModuleManagerImpl implements EclipseModuleManager, Persisten
|
||||
|
||||
@Override
|
||||
public Element getState() {
|
||||
if (!ClassPathStorageUtil.getStorageType(myModule).equals(JpsEclipseClasspathSerializer.CLASSPATH_STORAGE_ID)) {
|
||||
if (!myEclipseUrls.isEmpty() || !myEclipseVariablePaths.isEmpty() || myForceConfigureJDK || !myUnknownCons.isEmpty()) {
|
||||
Element root = new Element("EclipseModuleSettings");
|
||||
for (String eclipseUrl : myEclipseUrls) {
|
||||
final Element libElement = new Element(LIBELEMENT);
|
||||
libElement.setAttribute(VALUE_ATTR, eclipseUrl);
|
||||
root.addContent(libElement);
|
||||
}
|
||||
for (String var : myEclipseVariablePaths.keySet()) {
|
||||
Element varElement = new Element(VARELEMENT);
|
||||
if (var.startsWith(SRC_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, SRC_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, SRC_PREFIX);
|
||||
} else if (var.startsWith(SRC_LINK_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, SRC_LINK_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, SRC_LINK_PREFIX);
|
||||
} else if (var.startsWith(LINK_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, LINK_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, LINK_PREFIX);
|
||||
}
|
||||
else {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, var);
|
||||
}
|
||||
varElement.setAttribute(VALUE_ATTR, myEclipseVariablePaths.get(var));
|
||||
root.addContent(varElement);
|
||||
}
|
||||
for (String unknownCon : myUnknownCons) {
|
||||
Element conElement = new Element(CONELEMENT);
|
||||
conElement.setAttribute(VALUE_ATTR, unknownCon);
|
||||
root.addContent(conElement);
|
||||
}
|
||||
|
||||
if (myForceConfigureJDK) {
|
||||
root.setAttribute(FORCED_JDK, String.valueOf(true));
|
||||
}
|
||||
|
||||
final Element srcDescriptionElement = new Element(SRC_DESCRIPTION);
|
||||
srcDescriptionElement.setAttribute(EXPECTED_POSITION, String.valueOf(myExpectedModuleSourcePlace));
|
||||
for (String srcUrl : mySrcPlace.keySet()) {
|
||||
final Element srcFolder = new Element(SRC_FOLDER);
|
||||
srcFolder.setAttribute(VALUE_ATTR, srcUrl);
|
||||
srcFolder.setAttribute(EXPECTED_POSITION, mySrcPlace.get(srcUrl).toString());
|
||||
srcDescriptionElement.addContent(srcFolder);
|
||||
}
|
||||
root.addContent(srcDescriptionElement);
|
||||
|
||||
return root;
|
||||
}
|
||||
if (isEclipseStorage(myModule) ||
|
||||
myEclipseUrls.isEmpty() && myEclipseVariablePaths.isEmpty() && !myForceConfigureJDK && myUnknownCons.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
Element root = new Element("EclipseModuleSettings");
|
||||
|
||||
for (String eclipseUrl : myEclipseUrls) {
|
||||
root.addContent(new Element(LIBELEMENT).setAttribute(VALUE_ATTR, eclipseUrl));
|
||||
}
|
||||
|
||||
for (String var : myEclipseVariablePaths.keySet()) {
|
||||
Element varElement = new Element(VARELEMENT);
|
||||
if (var.startsWith(SRC_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, SRC_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, SRC_PREFIX);
|
||||
}
|
||||
else if (var.startsWith(SRC_LINK_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, SRC_LINK_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, SRC_LINK_PREFIX);
|
||||
}
|
||||
else if (var.startsWith(LINK_PREFIX)) {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, StringUtil.trimStart(var, LINK_PREFIX));
|
||||
varElement.setAttribute(PREFIX_ATTR, LINK_PREFIX);
|
||||
}
|
||||
else {
|
||||
varElement.setAttribute(VAR_ATTRIBUTE, var);
|
||||
}
|
||||
varElement.setAttribute(VALUE_ATTR, myEclipseVariablePaths.get(var));
|
||||
root.addContent(varElement);
|
||||
}
|
||||
|
||||
for (String unknownCon : myUnknownCons) {
|
||||
root.addContent(new Element(CONELEMENT).setAttribute(VALUE_ATTR, unknownCon));
|
||||
}
|
||||
|
||||
if (myForceConfigureJDK) {
|
||||
root.setAttribute(FORCED_JDK, String.valueOf(true));
|
||||
}
|
||||
|
||||
Element srcDescriptionElement = new Element(SRC_DESCRIPTION);
|
||||
srcDescriptionElement.setAttribute(EXPECTED_POSITION, String.valueOf(myExpectedModuleSourcePlace));
|
||||
for (String srcUrl : mySrcPlace.keySet()) {
|
||||
Element srcFolder = new Element(SRC_FOLDER);
|
||||
srcFolder.setAttribute(VALUE_ATTR, srcUrl);
|
||||
srcFolder.setAttribute(EXPECTED_POSITION, mySrcPlace.get(srcUrl).toString());
|
||||
srcDescriptionElement.addContent(srcFolder);
|
||||
}
|
||||
root.addContent(srcDescriptionElement);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(Element state) {
|
||||
clear();
|
||||
|
||||
for (Object o : state.getChildren(LIBELEMENT)) {
|
||||
myEclipseUrls.add(((Element)o).getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
for (Object o : state.getChildren(VARELEMENT)) {
|
||||
final String prefix = ((Element)o).getAttributeValue(PREFIX_ATTR);
|
||||
myEclipseVariablePaths.put(((Element)o).getAttributeValue(VAR_ATTRIBUTE), (prefix != null ? prefix : "") + ((Element)o).getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
for (Object o : state.getChildren(CONELEMENT)) {
|
||||
myUnknownCons.add(((Element)o).getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
final String forcedJdk = state.getAttributeValue(FORCED_JDK);
|
||||
myForceConfigureJDK = forcedJdk != null && Boolean.parseBoolean(forcedJdk);
|
||||
|
||||
final Element srcDescriptionElement = state.getChild(SRC_DESCRIPTION);
|
||||
if (srcDescriptionElement != null) {
|
||||
myExpectedModuleSourcePlace = Integer.parseInt(srcDescriptionElement.getAttributeValue(EXPECTED_POSITION));
|
||||
for (Object o : srcDescriptionElement.getChildren(SRC_FOLDER)) {
|
||||
mySrcPlace.put(((Element)o).getAttributeValue(VALUE_ATTR), Integer.parseInt(((Element)o).getAttributeValue(EXPECTED_POSITION)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
myEclipseUrls.clear();
|
||||
myEclipseVariablePaths.clear();
|
||||
myUnknownCons.clear();
|
||||
mySrcPlace.clear();
|
||||
myKnownCons.clear();
|
||||
|
||||
for (Element o : state.getChildren(LIBELEMENT)) {
|
||||
myEclipseUrls.add(o.getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
for (Element o : state.getChildren(VARELEMENT)) {
|
||||
myEclipseVariablePaths.put(o.getAttributeValue(VAR_ATTRIBUTE), o.getAttributeValue(PREFIX_ATTR, "") + o.getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
for (Element o : state.getChildren(CONELEMENT)) {
|
||||
myUnknownCons.add(o.getAttributeValue(VALUE_ATTR));
|
||||
}
|
||||
|
||||
myForceConfigureJDK = Boolean.parseBoolean(state.getAttributeValue(FORCED_JDK, "false"));
|
||||
|
||||
Element srcDescriptionElement = state.getChild(SRC_DESCRIPTION);
|
||||
if (srcDescriptionElement != null) {
|
||||
myExpectedModuleSourcePlace = Integer.parseInt(srcDescriptionElement.getAttributeValue(EXPECTED_POSITION));
|
||||
for (Element o : srcDescriptionElement.getChildren(SRC_FOLDER)) {
|
||||
mySrcPlace.put(o.getAttributeValue(VALUE_ATTR), Integer.parseInt(o.getAttributeValue(EXPECTED_POSITION)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -281,7 +282,8 @@ public class EclipseModuleManagerImpl implements EclipseModuleManager, Persisten
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSrcPlace(String srcUtl) {
|
||||
return mySrcPlace.get(srcUtl);
|
||||
public int getSrcPlace(String srcUtl) {
|
||||
Integer v = mySrcPlace.get(srcUtl);
|
||||
return v == null ? -1 : v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.output.EclipseJDOMUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
|
||||
import java.io.File;
|
||||
@@ -42,7 +43,7 @@ public class DotProjectFileHelper {
|
||||
private DotProjectFileHelper() {
|
||||
}
|
||||
|
||||
public static void saveDotProjectFile(Module module, String storageRoot) throws IOException {
|
||||
public static void saveDotProjectFile(@NotNull Module module, @NotNull String storageRoot) throws IOException {
|
||||
try {
|
||||
Document doc;
|
||||
if (ModuleType.get(module) instanceof JavaModuleType) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -31,19 +31,22 @@ import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.ProjectRootManagerImpl;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.EPathCommonUtil;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
import org.jetbrains.idea.eclipse.EclipseProjectFinder;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class EPathUtil {
|
||||
static final Logger LOG = Logger.getInstance("#" + EPathUtil.class.getName());
|
||||
static final Logger LOG = Logger.getInstance(EPathUtil.class);
|
||||
|
||||
private EPathUtil() {
|
||||
}
|
||||
@@ -173,9 +176,8 @@ public class EPathUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile getContentRoot(final ModuleRootModel model) {
|
||||
final VirtualFile[] contentRoots = model.getContentRoots();
|
||||
for (VirtualFile virtualFile : contentRoots) {
|
||||
public static VirtualFile getContentRoot(@NotNull ModuleRootModel model) {
|
||||
for (VirtualFile virtualFile : model.getContentRoots()) {
|
||||
if (virtualFile.findChild(EclipseXml.PROJECT_FILE) != null) {
|
||||
return virtualFile;
|
||||
}
|
||||
@@ -192,14 +194,15 @@ public class EPathUtil {
|
||||
if (file.getFileSystem() instanceof JarFileSystem) {
|
||||
final VirtualFile jarFile = JarFileSystem.getInstance().getVirtualFileForJar(file);
|
||||
if (jarFile == null) {
|
||||
LOG.assertTrue(false, "Url: \'" + url + "\'; file: " + file);
|
||||
LOG.error("Url: \'" + url + "\'; file: " + file);
|
||||
return ProjectRootManagerImpl.extractLocalPath(url);
|
||||
}
|
||||
file = jarFile;
|
||||
}
|
||||
if (contentRoot != null && VfsUtilCore.isAncestor(contentRoot, file, false)) { //inside current project
|
||||
return VfsUtilCore.getRelativePath(file, contentRoot, '/');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
final String path = collapse2eclipseRelative2OtherModule(project, file); //relative to other project
|
||||
if (path != null) {
|
||||
return path;
|
||||
|
||||
+21
-13
@@ -37,7 +37,9 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.*;
|
||||
import org.jetbrains.idea.eclipse.config.EclipseModuleManagerImpl;
|
||||
@@ -53,16 +55,17 @@ public class EclipseClasspathReader extends AbstractEclipseClasspathReader<Modif
|
||||
private final Project myProject;
|
||||
private ContentEntry myContentEntry;
|
||||
|
||||
public EclipseClasspathReader(final String rootPath, final Project project, @Nullable List<String> currentRoots) {
|
||||
public EclipseClasspathReader(@NotNull String rootPath, @NotNull Project project, @Nullable List<String> currentRoots) {
|
||||
this(rootPath, project, currentRoots, null);
|
||||
}
|
||||
|
||||
public EclipseClasspathReader(final String rootPath, final Project project, @Nullable List<String> currentRoots, @Nullable Set<String> moduleNames) {
|
||||
public EclipseClasspathReader(@NotNull String rootPath, @NotNull Project project, @Nullable List<String> currentRoots, @Nullable Set<String> moduleNames) {
|
||||
super(rootPath, currentRoots, moduleNames);
|
||||
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public void init(ModifiableRootModel model) {
|
||||
public void init(@NotNull ModifiableRootModel model) {
|
||||
myContentEntry = model.addContentEntry(pathToUrl(myRootPath));
|
||||
}
|
||||
|
||||
@@ -82,7 +85,7 @@ public class EclipseClasspathReader extends AbstractEclipseClasspathReader<Modif
|
||||
}
|
||||
}
|
||||
else if (Comparing.strEqual(kind, EclipseXml.SRC_KIND) || Comparing.strEqual(kind, EclipseXml.OUTPUT_KIND)) {
|
||||
final EclipseProjectFinder.LinkedResource linkedResource = EclipseProjectFinder.findLinkedResource(rootPath, path);
|
||||
EclipseProjectFinder.LinkedResource linkedResource = EclipseProjectFinder.findLinkedResource(rootPath, path);
|
||||
if (linkedResource != null && linkedResource.containsPathVariable()) {
|
||||
usedVariables.add(linkedResource.getVariableName());
|
||||
}
|
||||
@@ -90,9 +93,14 @@ public class EclipseClasspathReader extends AbstractEclipseClasspathReader<Modif
|
||||
}
|
||||
}
|
||||
|
||||
public void readClasspath(ModifiableRootModel model,
|
||||
final Collection<String> unknownLibraries,
|
||||
Collection<String> unknownJdks,
|
||||
public void readClasspath(@NotNull ModifiableRootModel model, @NotNull Element classpathElement) throws IOException, ConversionException {
|
||||
Set<String> sink = new THashSet<String>();
|
||||
readClasspath(model, sink, sink, sink, null, classpathElement);
|
||||
}
|
||||
|
||||
public void readClasspath(@NotNull ModifiableRootModel model,
|
||||
@NotNull Collection<String> unknownLibraries,
|
||||
@NotNull Collection<String> unknownJdks,
|
||||
Set<String> refsToModules,
|
||||
final String testPattern,
|
||||
Element classpathElement) throws IOException, ConversionException {
|
||||
@@ -102,11 +110,11 @@ public class EclipseClasspathReader extends AbstractEclipseClasspathReader<Modif
|
||||
}
|
||||
}
|
||||
int idx = 0;
|
||||
final EclipseModuleManagerImpl eclipseModuleManager = EclipseModuleManagerImpl.getInstance(model.getModule());
|
||||
final HashSet<String> libs = new HashSet<String>();
|
||||
for (Object o : classpathElement.getChildren(EclipseXml.CLASSPATHENTRY_TAG)) {
|
||||
EclipseModuleManagerImpl eclipseModuleManager = EclipseModuleManagerImpl.getInstance(model.getModule());
|
||||
Set<String> libs = new HashSet<String>();
|
||||
for (Element o : classpathElement.getChildren(EclipseXml.CLASSPATHENTRY_TAG)) {
|
||||
try {
|
||||
readClasspathEntry(model, unknownLibraries, unknownJdks, refsToModules, testPattern, (Element)o, idx++,
|
||||
readClasspathEntry(model, unknownLibraries, unknownJdks, refsToModules, testPattern, o, idx++,
|
||||
eclipseModuleManager,
|
||||
((BasePathMacroManager)PathMacroManager.getInstance(model.getModule())).getExpandMacroMap(), libs);
|
||||
}
|
||||
@@ -225,8 +233,8 @@ public class EclipseClasspathReader extends AbstractEclipseClasspathReader<Modif
|
||||
setOutputUrl(rootModel, path);
|
||||
}
|
||||
|
||||
public static void setOutputUrl(ModifiableRootModel rootModel, String path) {
|
||||
final CompilerModuleExtension compilerModuleExtension = rootModel.getModuleExtension(CompilerModuleExtension.class);
|
||||
public static void setOutputUrl(@NotNull ModifiableRootModel rootModel, @NotNull String path) {
|
||||
CompilerModuleExtension compilerModuleExtension = rootModel.getModuleExtension(CompilerModuleExtension.class);
|
||||
compilerModuleExtension.setCompilerOutputPath(pathToUrl(path));
|
||||
compilerModuleExtension.inheritCompilerOutputPath(false);
|
||||
}
|
||||
|
||||
+71
-71
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -26,92 +26,88 @@ import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.ConversionException;
|
||||
import org.jetbrains.idea.eclipse.EclipseModuleManager;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
import org.jetbrains.idea.eclipse.IdeaXml;
|
||||
import org.jetbrains.idea.eclipse.EclipseModuleManager;
|
||||
import org.jetbrains.idea.eclipse.config.EclipseModuleManagerImpl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EclipseClasspathWriter {
|
||||
private static final Logger LOG = Logger.getInstance("#" + EclipseClasspathWriter.class.getName());
|
||||
private final ModuleRootModel myModel;
|
||||
private final Map<String, Element> myOldEntries = new HashMap<String, Element>();
|
||||
public static final Logger LOG = Logger.getInstance(EclipseClasspathWriter.class);
|
||||
|
||||
public EclipseClasspathWriter(final ModuleRootModel model) {
|
||||
myModel = model;
|
||||
}
|
||||
private final Map<String, Element> myOldEntries = new THashMap<String, Element>();
|
||||
|
||||
public void writeClasspath(Element classpathElement, @Nullable Element oldRoot) throws ConversionException {
|
||||
@NotNull
|
||||
public Element writeClasspath(@Nullable Element oldRoot, @NotNull ModuleRootModel model) {
|
||||
Element classpathElement = new Element(EclipseXml.CLASSPATH_TAG);
|
||||
if (oldRoot != null) {
|
||||
for (Object o : oldRoot.getChildren(EclipseXml.CLASSPATHENTRY_TAG)) {
|
||||
final Element oldChild = (Element)o;
|
||||
final String oldKind = oldChild.getAttributeValue(EclipseXml.KIND_ATTR);
|
||||
final String oldPath = oldChild.getAttributeValue(EclipseXml.PATH_ATTR);
|
||||
for (Element oldChild : oldRoot.getChildren(EclipseXml.CLASSPATHENTRY_TAG)) {
|
||||
String oldKind = oldChild.getAttributeValue(EclipseXml.KIND_ATTR);
|
||||
String oldPath = oldChild.getAttributeValue(EclipseXml.PATH_ATTR);
|
||||
myOldEntries.put(oldKind + getJREKey(oldPath), oldChild);
|
||||
}
|
||||
}
|
||||
|
||||
for (OrderEntry orderEntry : myModel.getOrderEntries()) {
|
||||
createClasspathEntry(orderEntry, classpathElement);
|
||||
for (OrderEntry orderEntry : model.getOrderEntries()) {
|
||||
createClasspathEntry(orderEntry, classpathElement, model);
|
||||
}
|
||||
|
||||
@NonNls String outputPath = "bin";
|
||||
final String compilerOutputUrl = myModel.getModuleExtension(CompilerModuleExtension.class).getCompilerOutputUrl();
|
||||
final EclipseModuleManager eclipseModuleManager = EclipseModuleManagerImpl.getInstance(myModel.getModule());
|
||||
String outputPath = "bin";
|
||||
final String compilerOutputUrl = model.getModuleExtension(CompilerModuleExtension.class).getCompilerOutputUrl();
|
||||
final EclipseModuleManager eclipseModuleManager = EclipseModuleManagerImpl.getInstance(model.getModule());
|
||||
final String linkedPath = eclipseModuleManager.getEclipseLinkedVarPath(compilerOutputUrl);
|
||||
if (linkedPath != null) {
|
||||
outputPath = linkedPath;
|
||||
} else {
|
||||
final VirtualFile contentRoot = EPathUtil.getContentRoot(myModel);
|
||||
final VirtualFile output = myModel.getModuleExtension(CompilerModuleExtension.class).getCompilerOutputPath();
|
||||
if (contentRoot != null && output != null && VfsUtil.isAncestor(contentRoot, output, false)) {
|
||||
outputPath = EPathUtil.collapse2EclipsePath(output.getUrl(), myModel);
|
||||
}
|
||||
else {
|
||||
VirtualFile contentRoot = EPathUtil.getContentRoot(model);
|
||||
VirtualFile output = model.getModuleExtension(CompilerModuleExtension.class).getCompilerOutputPath();
|
||||
if (contentRoot != null && output != null && VfsUtilCore.isAncestor(contentRoot, output, false)) {
|
||||
outputPath = EPathUtil.collapse2EclipsePath(output.getUrl(), model);
|
||||
}
|
||||
else if (output == null && compilerOutputUrl != null) {
|
||||
outputPath = EPathUtil.collapse2EclipsePath(compilerOutputUrl, myModel);
|
||||
outputPath = EPathUtil.collapse2EclipsePath(compilerOutputUrl, model);
|
||||
}
|
||||
}
|
||||
for (String support : eclipseModuleManager.getUsedCons()) {
|
||||
final Integer place = eclipseModuleManager.getSrcPlace(support);
|
||||
addOrderEntry(EclipseXml.CON_KIND, support, classpathElement, place != null ? place.intValue() : -1);
|
||||
addOrderEntry(EclipseXml.CON_KIND, support, classpathElement, eclipseModuleManager.getSrcPlace(support));
|
||||
}
|
||||
final Element orderEntry = addOrderEntry(EclipseXml.OUTPUT_KIND, outputPath, classpathElement);
|
||||
setAttributeIfAbsent(orderEntry, EclipseXml.PATH_ATTR, EclipseXml.BIN_DIR);
|
||||
setAttributeIfAbsent(addOrderEntry(EclipseXml.OUTPUT_KIND, outputPath, classpathElement), EclipseXml.PATH_ATTR, EclipseXml.BIN_DIR);
|
||||
|
||||
return classpathElement;
|
||||
}
|
||||
|
||||
private void createClasspathEntry(OrderEntry entry, Element classpathRoot) throws ConversionException {
|
||||
final EclipseModuleManager eclipseModuleManager = EclipseModuleManagerImpl.getInstance(entry.getOwnerModule());
|
||||
private void createClasspathEntry(@NotNull OrderEntry entry, @NotNull Element classpathRoot, @NotNull ModuleRootModel model) throws ConversionException {
|
||||
EclipseModuleManager eclipseModuleManager = EclipseModuleManagerImpl.getInstance(entry.getOwnerModule());
|
||||
if (entry instanceof ModuleSourceOrderEntry) {
|
||||
final boolean shouldPlaceSeparately =
|
||||
eclipseModuleManager.isExpectedModuleSourcePlace(Arrays.binarySearch(myModel.getOrderEntries(), entry));
|
||||
final ContentEntry[] entries = myModel.getContentEntries();
|
||||
for (final ContentEntry contentEntry : entries) {
|
||||
final VirtualFile contentRoot = contentEntry.getFile();
|
||||
boolean shouldPlaceSeparately = eclipseModuleManager.isExpectedModuleSourcePlace(Arrays.binarySearch(model.getOrderEntries(), entry));
|
||||
for (ContentEntry contentEntry : model.getContentEntries()) {
|
||||
VirtualFile contentRoot = contentEntry.getFile();
|
||||
for (SourceFolder sourceFolder : contentEntry.getSourceFolders()) {
|
||||
final String srcUrl = sourceFolder.getUrl();
|
||||
String relativePath = EPathUtil.collapse2EclipsePath(srcUrl, myModel);
|
||||
if (!Comparing.equal(contentRoot, EPathUtil.getContentRoot(myModel))) {
|
||||
final String linkedPath = EclipseModuleManagerImpl.getInstance(entry.getOwnerModule()).getEclipseLinkedSrcVariablePath(srcUrl);
|
||||
String srcUrl = sourceFolder.getUrl();
|
||||
String relativePath = EPathUtil.collapse2EclipsePath(srcUrl, model);
|
||||
if (!Comparing.equal(contentRoot, EPathUtil.getContentRoot(model))) {
|
||||
String linkedPath = EclipseModuleManagerImpl.getInstance(entry.getOwnerModule()).getEclipseLinkedSrcVariablePath(srcUrl);
|
||||
if (linkedPath != null) {
|
||||
relativePath = linkedPath;
|
||||
}
|
||||
}
|
||||
final Integer idx = eclipseModuleManager.getSrcPlace(srcUrl);
|
||||
addOrderEntry(EclipseXml.SRC_KIND, relativePath, classpathRoot, shouldPlaceSeparately && idx != null ? idx.intValue() : -1);
|
||||
int index = eclipseModuleManager.getSrcPlace(srcUrl);
|
||||
addOrderEntry(EclipseXml.SRC_KIND, relativePath, classpathRoot, shouldPlaceSeparately && index != -1 ? index : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (entry instanceof ModuleOrderEntry) {
|
||||
Element orderEntry = addOrderEntry(EclipseXml.SRC_KIND, "/" + ((ModuleOrderEntry)entry).getModuleName(), classpathRoot);
|
||||
Element orderEntry = addOrderEntry(EclipseXml.SRC_KIND, '/' + ((ModuleOrderEntry)entry).getModuleName(), classpathRoot);
|
||||
setAttributeIfAbsent(orderEntry, EclipseXml.COMBINEACCESSRULES_ATTR, EclipseXml.FALSE_VALUE);
|
||||
setExported(orderEntry, ((ExportableOrderEntry)entry));
|
||||
}
|
||||
@@ -149,20 +145,20 @@ public class EclipseClasspathWriter {
|
||||
}
|
||||
else {
|
||||
LOG.assertTrue(!StringUtil.isEmptyOrSpaces(files[0]), "Library: " + libraryName);
|
||||
orderEntry = addOrderEntry(EclipseXml.LIB_KIND, EPathUtil.collapse2EclipsePath(files[0], myModel), classpathRoot);
|
||||
orderEntry = addOrderEntry(EclipseXml.LIB_KIND, EPathUtil.collapse2EclipsePath(files[0], model), classpathRoot);
|
||||
}
|
||||
|
||||
final String srcRelativePath;
|
||||
String eclipseSrcVariablePath = null;
|
||||
|
||||
boolean addSrcRoots = true;
|
||||
final String[] srcFiles = libraryOrderEntry.getRootUrls(OrderRootType.SOURCES);
|
||||
String[] srcFiles = libraryOrderEntry.getRootUrls(OrderRootType.SOURCES);
|
||||
if (srcFiles.length == 0) {
|
||||
srcRelativePath = null;
|
||||
}
|
||||
else {
|
||||
final String srcFile = srcFiles[0];
|
||||
srcRelativePath = EPathUtil.collapse2EclipsePath(srcFile, myModel);
|
||||
srcRelativePath = EPathUtil.collapse2EclipsePath(srcFile, model);
|
||||
if (eclipseVariablePath != null) {
|
||||
eclipseSrcVariablePath = eclipseModuleManager.getEclipseSrcVariablePath(srcFile);
|
||||
if (eclipseSrcVariablePath == null) {
|
||||
@@ -172,10 +168,11 @@ public class EclipseClasspathWriter {
|
||||
eclipseSrcVariablePath = EPathUtil.collapse2EclipseVariabledPath(libraryOrderEntry, OrderRootType.SOURCES);
|
||||
if (eclipseSrcVariablePath != null) {
|
||||
eclipseSrcVariablePath = "/" + eclipseSrcVariablePath;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (newVarLibrary) { //new library which cannot be replaced with vars
|
||||
orderEntry.detach();
|
||||
orderEntry = addOrderEntry(EclipseXml.LIB_KIND, EPathUtil.collapse2EclipsePath(files[0], myModel), classpathRoot);
|
||||
orderEntry = addOrderEntry(EclipseXml.LIB_KIND, EPathUtil.collapse2EclipsePath(files[0], model), classpathRoot);
|
||||
}
|
||||
else {
|
||||
LOG.info("Added root " + srcRelativePath + " (in existing var library) can't be replaced with any variable; src roots placed in .eml only");
|
||||
@@ -187,20 +184,21 @@ public class EclipseClasspathWriter {
|
||||
}
|
||||
setOrRemoveAttribute(orderEntry, EclipseXml.SOURCEPATH_ATTR, addSrcRoots ? (eclipseSrcVariablePath != null ? eclipseSrcVariablePath : srcRelativePath) : null);
|
||||
|
||||
EJavadocUtil.setupJavadocAttributes(orderEntry, libraryOrderEntry, myModel);
|
||||
EJavadocUtil.setupJavadocAttributes(orderEntry, libraryOrderEntry, model);
|
||||
setExported(orderEntry, libraryOrderEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Element orderEntry;
|
||||
Element orderEntry;
|
||||
if (eclipseModuleManager.getUnknownCons().contains(libraryName)) {
|
||||
orderEntry = addOrderEntry(EclipseXml.CON_KIND, libraryName, classpathRoot);
|
||||
} else if (Comparing.strEqual(libraryName, IdeaXml.ECLIPSE_LIBRARY)) {
|
||||
}
|
||||
else if (Comparing.strEqual(libraryName, IdeaXml.ECLIPSE_LIBRARY)) {
|
||||
orderEntry = addOrderEntry(EclipseXml.CON_KIND, EclipseXml.ECLIPSE_PLATFORM, classpathRoot);
|
||||
}
|
||||
else {
|
||||
orderEntry = addOrderEntry(EclipseXml.CON_KIND, EclipseXml.USER_LIBRARY + "/" + libraryName, classpathRoot);
|
||||
orderEntry = addOrderEntry(EclipseXml.CON_KIND, EclipseXml.USER_LIBRARY + '/' + libraryName, classpathRoot);
|
||||
}
|
||||
setExported(orderEntry, libraryOrderEntry);
|
||||
}
|
||||
@@ -222,7 +220,7 @@ public class EclipseClasspathWriter {
|
||||
if (jdk.getSdkType() instanceof JavaSdkType) {
|
||||
jdkLink += EclipseXml.JAVA_SDK_TYPE;
|
||||
}
|
||||
jdkLink += "/" + jdk.getName();
|
||||
jdkLink += '/' + jdk.getName();
|
||||
}
|
||||
addOrderEntry(EclipseXml.CON_KIND, jdkLink, classpathRoot);
|
||||
}
|
||||
@@ -236,26 +234,29 @@ public class EclipseClasspathWriter {
|
||||
return addOrderEntry(kind, path, classpathRoot, -1);
|
||||
}
|
||||
|
||||
private Element addOrderEntry(String kind, String path, Element classpathRoot, int idx) {
|
||||
final Element element = myOldEntries.get(kind + getJREKey(path));
|
||||
if (element != null){
|
||||
final Element clonedElement = (Element)element.clone();
|
||||
if (idx == -1 || idx >= classpathRoot.getContentSize()) {
|
||||
private Element addOrderEntry(@NotNull String kind, String path, Element classpathRoot, int index) {
|
||||
Element element = myOldEntries.get(kind + getJREKey(path));
|
||||
if (element != null) {
|
||||
Element clonedElement = element.clone();
|
||||
if (index == -1 || index >= classpathRoot.getContentSize()) {
|
||||
classpathRoot.addContent(clonedElement);
|
||||
} else {
|
||||
classpathRoot.addContent(idx, clonedElement);
|
||||
}
|
||||
else {
|
||||
classpathRoot.addContent(index, clonedElement);
|
||||
}
|
||||
return clonedElement;
|
||||
}
|
||||
|
||||
Element orderEntry = new Element(EclipseXml.CLASSPATHENTRY_TAG);
|
||||
orderEntry.setAttribute(EclipseXml.KIND_ATTR, kind);
|
||||
if (path != null) {
|
||||
orderEntry.setAttribute(EclipseXml.PATH_ATTR, path);
|
||||
}
|
||||
if (idx == -1) {
|
||||
if (index == -1) {
|
||||
classpathRoot.addContent(orderEntry);
|
||||
} else {
|
||||
classpathRoot.addContent(idx, orderEntry);
|
||||
}
|
||||
else {
|
||||
classpathRoot.addContent(index, orderEntry);
|
||||
}
|
||||
return orderEntry;
|
||||
}
|
||||
@@ -268,19 +269,18 @@ public class EclipseClasspathWriter {
|
||||
setOrRemoveAttribute(orderEntry, EclipseXml.EXPORTED_ATTR, dependency.isExported() ? EclipseXml.TRUE_VALUE : null);
|
||||
}
|
||||
|
||||
private static void setOrRemoveAttribute(Element element, String name, String value) {
|
||||
if (value != null) {
|
||||
element.setAttribute(name, value);
|
||||
private static void setOrRemoveAttribute(@NotNull Element element, @NotNull String name, @Nullable String value) {
|
||||
if (value == null) {
|
||||
element.removeAttribute(name);
|
||||
}
|
||||
else {
|
||||
element.removeAttribute(name);
|
||||
element.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setAttributeIfAbsent(Element element, String name, String value) {
|
||||
private static void setAttributeIfAbsent(@NotNull Element element, String name, String value) {
|
||||
if (element.getAttribute(name) == null) {
|
||||
element.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
-29
@@ -32,16 +32,15 @@ import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.eclipse.IdeaXml;
|
||||
import org.jetbrains.idea.eclipse.config.EclipseModuleManagerImpl;
|
||||
@@ -66,10 +65,6 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
@NonNls private static final String JAVADOCROOT_ATTR = "javadocroot_attr";
|
||||
public static final String INHERIT_JDK = "inheritJdk";
|
||||
|
||||
@Override
|
||||
protected void readLibraryLevels(Element root, Map<String, String> levels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContentEntry[] getEntries(ModifiableRootModel model) {
|
||||
return model.getContentEntries();
|
||||
@@ -245,12 +240,10 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean writeIDEASpecificClasspath(final Element root, ModuleRootModel model) throws WriteExternalException {
|
||||
|
||||
public static boolean writeIdeaSpecificClasspath(@NotNull Element root, @NotNull ModuleRootModel model) {
|
||||
boolean isModified = false;
|
||||
|
||||
final CompilerModuleExtension compilerModuleExtension = model.getModuleExtension(CompilerModuleExtension.class);
|
||||
|
||||
CompilerModuleExtension compilerModuleExtension = model.getModuleExtension(CompilerModuleExtension.class);
|
||||
if (compilerModuleExtension.getCompilerOutputUrlForTests() != null) {
|
||||
final Element pathElement = new Element(IdeaXml.OUTPUT_TEST_TAG);
|
||||
pathElement.setAttribute(IdeaXml.URL_ATTR, compilerModuleExtension.getCompilerOutputUrlForTests());
|
||||
@@ -266,15 +259,14 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
isModified = true;
|
||||
}
|
||||
|
||||
final LanguageLevelModuleExtensionImpl languageLevelModuleExtension = model.getModuleExtension(LanguageLevelModuleExtensionImpl.class);
|
||||
final LanguageLevel languageLevel = languageLevelModuleExtension.getLanguageLevel();
|
||||
if (languageLevel != null) {
|
||||
LanguageLevelModuleExtensionImpl languageLevelModuleExtension = model.getModuleExtension(LanguageLevelModuleExtensionImpl.class);
|
||||
if (languageLevelModuleExtension.getLanguageLevel() != null) {
|
||||
languageLevelModuleExtension.writeExternal(root);
|
||||
isModified = true;
|
||||
}
|
||||
|
||||
for (ContentEntry entry : model.getContentEntries()) {
|
||||
final Element contentEntryElement = new Element(IdeaXml.CONTENT_ENTRY_TAG);
|
||||
Element contentEntryElement = new Element(IdeaXml.CONTENT_ENTRY_TAG);
|
||||
contentEntryElement.setAttribute(IdeaXml.URL_ATTR, entry.getUrl());
|
||||
root.addContent(contentEntryElement);
|
||||
for (SourceFolder sourceFolder : entry.getSourceFolders()) {
|
||||
@@ -284,7 +276,7 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
element.setAttribute(IdeaXml.URL_ATTR, sourceFolder.getUrl());
|
||||
isModified = true;
|
||||
}
|
||||
final String packagePrefix = sourceFolder.getPackagePrefix();
|
||||
String packagePrefix = sourceFolder.getPackagePrefix();
|
||||
if (!StringUtil.isEmptyOrSpaces(packagePrefix)) {
|
||||
Element element = new Element(IdeaXml.PACKAGE_PREFIX_TAG);
|
||||
contentEntryElement.addContent(element);
|
||||
@@ -294,20 +286,19 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
}
|
||||
}
|
||||
|
||||
final VirtualFile entryFile = entry.getFile();
|
||||
VirtualFile entryFile = entry.getFile();
|
||||
for (ExcludeFolder excludeFolder : entry.getExcludeFolders()) {
|
||||
final String exludeFolderUrl = excludeFolder.getUrl();
|
||||
final VirtualFile excludeFile = excludeFolder.getFile();
|
||||
VirtualFile excludeFile = excludeFolder.getFile();
|
||||
if (entryFile == null || excludeFile == null || VfsUtilCore.isAncestor(entryFile, excludeFile, false)) {
|
||||
Element element = new Element(IdeaXml.EXCLUDE_FOLDER_TAG);
|
||||
contentEntryElement.addContent(element);
|
||||
element.setAttribute(IdeaXml.URL_ATTR, exludeFolderUrl);
|
||||
element.setAttribute(IdeaXml.URL_ATTR, excludeFolder.getUrl());
|
||||
isModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String, String> libLevels = new LinkedHashMap<String, String>();
|
||||
Map<String, String> libLevels = new LinkedHashMap<String, String>();
|
||||
for (OrderEntry entry : model.getOrderEntries()) {
|
||||
if (entry instanceof ModuleOrderEntry) {
|
||||
final DependencyScope scope = ((ModuleOrderEntry)entry).getScope();
|
||||
@@ -324,7 +315,8 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
if (EclipseModuleManagerImpl.getInstance(entry.getOwnerModule()).getInvalidJdk() != null || jdk != null) {
|
||||
if (entry instanceof InheritedJdkOrderEntry) {
|
||||
root.setAttribute(INHERIT_JDK, "true");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
root.setAttribute("jdk", ((JdkOrderEntry)entry).getJdkName());
|
||||
if (jdk != null) {
|
||||
root.setAttribute("jdk_type", jdk.getSdkType().getName());
|
||||
@@ -335,10 +327,10 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
}
|
||||
if (!(entry instanceof LibraryOrderEntry)) continue;
|
||||
|
||||
final Element element = new Element("lib");
|
||||
Element element = new Element("lib");
|
||||
element.setAttribute("name", entry.getPresentableName());
|
||||
final LibraryOrderEntry libraryEntry = (LibraryOrderEntry)entry;
|
||||
final DependencyScope scope = libraryEntry.getScope();
|
||||
LibraryOrderEntry libraryEntry = (LibraryOrderEntry)entry;
|
||||
DependencyScope scope = libraryEntry.getScope();
|
||||
element.setAttribute("scope", scope.name());
|
||||
if (libraryEntry.isModuleLevel()) {
|
||||
final String[] urls = libraryEntry.getRootUrls(OrderRootType.SOURCES);
|
||||
@@ -360,7 +352,7 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
}
|
||||
|
||||
final String[] javadocUrls = libraryEntry.getRootUrls(JavadocOrderRootType.getInstance());
|
||||
for (int i = 1; i < javadocUrls.length; i++) {
|
||||
for (int i = 1; i < javadocUrls.length; i++) {
|
||||
Element javadocElement = new Element(JAVADOCROOT_ATTR);
|
||||
javadocElement.setAttribute("url", javadocUrls[i]);
|
||||
element.addContent(javadocElement);
|
||||
@@ -383,8 +375,9 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
isModified = true;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
final String libraryLevel = libraryEntry.getLibraryLevel();
|
||||
}
|
||||
else {
|
||||
String libraryLevel = libraryEntry.getLibraryLevel();
|
||||
if (!LibraryTablesRegistrar.APPLICATION_LEVEL.equals(libraryLevel)) {
|
||||
libLevels.put(libraryEntry.getLibraryName(), libraryLevel);
|
||||
}
|
||||
@@ -396,9 +389,9 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings<Modifiabl
|
||||
}
|
||||
|
||||
if (!libLevels.isEmpty()) {
|
||||
final Element libLevelsElement = new Element("levels");
|
||||
Element libLevelsElement = new Element("levels");
|
||||
for (String libName : libLevels.keySet()) {
|
||||
final Element libElement = new Element("level");
|
||||
Element libElement = new Element("level");
|
||||
libElement.setAttribute("name", libName);
|
||||
libElement.setAttribute("value", libLevels.get(libName));
|
||||
libLevelsElement.addContent(libElement);
|
||||
|
||||
+5
-16
@@ -26,11 +26,9 @@ import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ModuleRootModel;
|
||||
import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil;
|
||||
import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
|
||||
import com.intellij.openapi.roots.impl.storage.ClasspathStorageProvider;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -39,10 +37,10 @@ import com.intellij.util.SmartList;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.output.EclipseJDOMUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.eclipse.ConversionException;
|
||||
import org.jetbrains.idea.eclipse.EclipseBundle;
|
||||
import org.jetbrains.idea.eclipse.EclipseXml;
|
||||
import org.jetbrains.idea.eclipse.IdeaXml;
|
||||
import org.jetbrains.idea.eclipse.config.EclipseModuleManagerImpl;
|
||||
import org.jetbrains.idea.eclipse.conversion.DotProjectFileHelper;
|
||||
import org.jetbrains.idea.eclipse.conversion.EclipseClasspathWriter;
|
||||
import org.jetbrains.idea.eclipse.conversion.EclipseUserLibrariesHelper;
|
||||
@@ -74,7 +72,7 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware {
|
||||
List<Module> modules = new SmartList<Module>();
|
||||
List<Module> incompatibleModules = new SmartList<Module>();
|
||||
for (Module module : ModuleManager.getInstance(project).getModules()) {
|
||||
if (!JpsEclipseClasspathSerializer.CLASSPATH_STORAGE_ID.equals(ClassPathStorageUtil.getStorageType(module))) {
|
||||
if (!EclipseModuleManagerImpl.isEclipseStorage(module)) {
|
||||
try {
|
||||
ClasspathStorageProvider provider = ClasspathStorage.getProvider(JpsEclipseClasspathSerializer.CLASSPATH_STORAGE_ID);
|
||||
if (provider != null) {
|
||||
@@ -125,10 +123,7 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware {
|
||||
VirtualFile[] contentRoots = model.getContentRoots();
|
||||
String storageRoot = contentRoots.length == 1 ? contentRoots[0].getPath() : ClasspathStorage.getStorageRootFromOptions(module);
|
||||
try {
|
||||
Element classpathElement = new Element(EclipseXml.CLASSPATH_TAG);
|
||||
|
||||
EclipseClasspathWriter classpathWriter = new EclipseClasspathWriter(model);
|
||||
classpathWriter.writeClasspath(classpathElement, null);
|
||||
Element classpathElement = new EclipseClasspathWriter().writeClasspath(null, model);
|
||||
File classpathFile = new File(storageRoot, EclipseXml.CLASSPATH_FILE);
|
||||
if (!FileUtil.createIfDoesntExist(classpathFile)) {
|
||||
continue;
|
||||
@@ -136,7 +131,7 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware {
|
||||
EclipseJDOMUtil.output(classpathElement, classpathFile, project);
|
||||
|
||||
final Element ideaSpecific = new Element(IdeaXml.COMPONENT_TAG);
|
||||
if (IdeaSpecificSettings.writeIDEASpecificClasspath(ideaSpecific, model)) {
|
||||
if (IdeaSpecificSettings.writeIdeaSpecificClasspath(ideaSpecific, model)) {
|
||||
File emlFile = new File(storageRoot, module.getName() + EclipseXml.IDEA_SETTINGS_POSTFIX);
|
||||
if (!FileUtil.createIfDoesntExist(emlFile)) {
|
||||
continue;
|
||||
@@ -146,13 +141,7 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware {
|
||||
|
||||
DotProjectFileHelper.saveDotProjectFile(module, storageRoot);
|
||||
}
|
||||
catch (ConversionException e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
catch (WriteExternalException e1) {
|
||||
catch (Exception e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -57,6 +57,7 @@ import com.intellij.projectImport.ProjectImportBuilder;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import icons.EclipseIcons;
|
||||
import org.jdom.Element;
|
||||
@@ -173,8 +174,8 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
|
||||
|
||||
public boolean validate(final Project currentProject, final Project dstProject) {
|
||||
final Ref<Exception> refEx = new Ref<Exception>();
|
||||
final HashSet<String> variables = new HashSet<String>();
|
||||
final Map<String, String> naturesNames = new HashMap<String, String>();
|
||||
final Set<String> variables = new THashSet<String>();
|
||||
final Map<String, String> naturesNames = new THashMap<String, String>();
|
||||
final List<String> projectsToConvert = getParameters().projectsToConvert;
|
||||
final boolean oneProjectToConvert = projectsToConvert.size() == 1;
|
||||
final String separator = oneProjectToConvert ? "<br>" : ", ";
|
||||
@@ -272,7 +273,7 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
|
||||
return file.getPath();
|
||||
}
|
||||
}, "\n") +
|
||||
".\n Would you like to reuse them?", "Module files found",
|
||||
".\n Would you like to reuse them?", "Module Files Found",
|
||||
Messages.getQuestionIcon());
|
||||
if (resultCode != Messages.YES) {
|
||||
if (resultCode == Messages.NO) {
|
||||
@@ -318,7 +319,7 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
|
||||
final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, getParameters().projectsToConvert, moduleNames);
|
||||
classpathReader.init(rootModel);
|
||||
if (classpathFile.exists()) {
|
||||
final Element classpathElement = JDOMUtil.loadDocument(classpathFile).getRootElement();
|
||||
Element classpathElement = JDOMUtil.load(classpathFile);
|
||||
classpathReader.readClasspath(rootModel, unknownLibraries, unknownJdks, refsToModules,
|
||||
getParameters().converterOptions.testPattern, classpathElement);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
@@ -48,7 +47,6 @@ import org.jetbrains.idea.eclipse.conversion.EclipseClasspathWriter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public class EclipseClasspathTest extends IdeaTestCase {
|
||||
@Override
|
||||
@@ -92,10 +90,9 @@ public class EclipseClasspathTest extends IdeaTestCase {
|
||||
@Override
|
||||
public void consume(ModifiableRootModel model) {
|
||||
try {
|
||||
Set<String> sink = ContainerUtil.newHashSet();
|
||||
EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, null);
|
||||
classpathReader.init(model);
|
||||
classpathReader.readClasspath(model, sink, sink, sink, null, classpathElement);
|
||||
classpathReader.readClasspath(model, classpathElement);
|
||||
new EclipseClasspathStorageProvider().assertCompatible(model);
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -113,10 +110,10 @@ public class EclipseClasspathTest extends IdeaTestCase {
|
||||
if (!SystemInfo.isWindows) {
|
||||
fileText1 = fileText1.replaceAll(EclipseXml.FILE_PROTOCOL + "/", EclipseXml.FILE_PROTOCOL);
|
||||
}
|
||||
final Element classpathElement1 = JDOMUtil.loadDocument(fileText1).getRootElement();
|
||||
final ModuleRootModel model = ModuleRootManager.getInstance(module);
|
||||
final Element resultClasspathElement = new Element(EclipseXml.CLASSPATH_TAG);
|
||||
new EclipseClasspathWriter(model).writeClasspath(resultClasspathElement, classpathElement1);
|
||||
|
||||
Element classpathElement1 = JDOMUtil.loadDocument(fileText1).getRootElement();
|
||||
ModuleRootModel model = ModuleRootManager.getInstance(module);
|
||||
Element resultClasspathElement = new EclipseClasspathWriter().writeClasspath(classpathElement1, model);
|
||||
|
||||
String resulted = new String(JDOMUtil.printDocument(new Document(resultClasspathElement), "\n"));
|
||||
assertTrue(resulted.replaceAll(StringUtil.escapeToRegexp(module.getProject().getBaseDir().getPath()), "\\$ROOT\\$"),
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
*/
|
||||
package org.jetbrains.idea.eclipse;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.StdModuleTypes;
|
||||
@@ -31,7 +31,10 @@ import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ModuleRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
@@ -39,7 +42,8 @@ import junit.framework.Assert;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.idea.eclipse.config.EclipseClasspathStorageProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.eclipse.config.EclipseClasspathConverter;
|
||||
import org.jetbrains.idea.eclipse.conversion.IdeaSpecificSettings;
|
||||
|
||||
import java.io.File;
|
||||
@@ -67,34 +71,34 @@ public class EclipseEmlTest extends IdeaTestCase {
|
||||
checkModule(path, module);
|
||||
}
|
||||
|
||||
private static Module doLoadModule(final String path, final Project project) throws IOException, JDOMException, InvalidDataException {
|
||||
final Module module = WriteCommandAction.runWriteCommandAction(null, new Computable<Module>() {
|
||||
@Override
|
||||
public Module compute() {
|
||||
return ModuleManager.getInstance(project)
|
||||
.newModule(path + "/" + EclipseProjectFinder.findProjectName(path) + IdeaXml.IML_EXT, StdModuleTypes.JAVA.getId());
|
||||
}
|
||||
});
|
||||
private static Module doLoadModule(@NotNull String path, @NotNull Project project) throws IOException, JDOMException, InvalidDataException {
|
||||
Module module;
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
module = ModuleManager.getInstance(project).newModule(path + '/' + EclipseProjectFinder.findProjectName(path) + IdeaXml.IML_EXT, StdModuleTypes.JAVA.getId());
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
replaceRoot(path, EclipseXml.DOT_CLASSPATH_EXT, project);
|
||||
|
||||
|
||||
EclipseClasspathStorageProvider.EclipseClasspathConverter converter = new EclipseClasspathStorageProvider.EclipseClasspathConverter(module);
|
||||
final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
|
||||
converter.getClasspath(rootModel, JDOMUtil.load(new File(path, EclipseXml.DOT_CLASSPATH_EXT)));
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
rootModel.commit();
|
||||
}
|
||||
});
|
||||
ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
new EclipseClasspathConverter(module).readClasspath(rootModel);
|
||||
token = WriteAction.start();
|
||||
try {
|
||||
rootModel.commit();
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
protected static void checkModule(String path, Module module) throws WriteExternalException, IOException, JDOMException {
|
||||
ModuleRootModel rootModel = ModuleRootManager.getInstance(module);
|
||||
final Element root = new Element("component");
|
||||
IdeaSpecificSettings.writeIDEASpecificClasspath(root, rootModel);
|
||||
IdeaSpecificSettings.writeIdeaSpecificClasspath(root, rootModel);
|
||||
|
||||
final String resulted = new String(JDOMUtil.printDocument(new Document(root), "\n"));
|
||||
|
||||
|
||||
@@ -39,13 +39,11 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.idea.eclipse.conversion.EclipseClasspathReader;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class EclipseImlTest extends IdeaTestCase {
|
||||
@NonNls private static final String JUNIT = "JUNIT";
|
||||
@@ -86,9 +84,9 @@ public class EclipseImlTest extends IdeaTestCase {
|
||||
}
|
||||
});
|
||||
final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, null);
|
||||
EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, null);
|
||||
classpathReader.init(rootModel);
|
||||
classpathReader.readClasspath(rootModel, new ArrayList<String>(), new ArrayList<String>(), new THashSet<String>(), null, classpathElement);
|
||||
classpathReader.readClasspath(rootModel, classpathElement);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
rootModel.commit();
|
||||
|
||||
Reference in New Issue
Block a user