Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir.Orlov
2014-10-27 22:04:09 +03:00
51 changed files with 1370 additions and 968 deletions
@@ -71,9 +71,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.api.BasicFuture;
import org.jetbrains.jps.api.CmdlineProtoUtil;
import org.jetbrains.jps.api.CmdlineRemoteProto;
import org.jetbrains.jps.api.TaskFuture;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import javax.swing.*;
@@ -138,7 +138,7 @@ public class CompileDriver {
return;
}
try {
final BasicFuture future = compileInExternalProcess(compileContext, true);
final TaskFuture future = compileInExternalProcess(compileContext, true);
if (future != null) {
while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) {
if (indicator.isCanceled()) {
@@ -194,7 +194,7 @@ public class CompileDriver {
}
@Nullable
private BasicFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate)
private TaskFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate)
throws Exception {
final CompileScope scope = compileContext.getCompileScope();
final Collection<String> paths = CompileScopeUtil.fetchFiles(compileContext);
@@ -400,7 +400,7 @@ public class CompileDriver {
return;
}
final BasicFuture future = compileInExternalProcess(compileContext, false);
final TaskFuture future = compileInExternalProcess(compileContext, false);
if (future != null) {
while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) {
if (indicator.isCanceled()) {
@@ -100,7 +100,8 @@ import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.model.serialization.JpsGlobalLoader;
import javax.tools.*;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.awt.*;
import java.io.File;
import java.io.IOException;
@@ -108,8 +109,7 @@ import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.*;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
@@ -148,10 +148,10 @@ public class BuildManager implements ApplicationComponent{
private final File mySystemDirectory;
private final ProjectManager myProjectManager;
private final Map<BasicFuture, Project> myAutomakeFutures = Collections.synchronizedMap(new HashMap<BasicFuture, Project>());
private final Map<TaskFuture, Project> myAutomakeFutures = Collections.synchronizedMap(new HashMap<TaskFuture, Project>());
private final Map<String, RequestFuture> myBuildsInProgress = Collections.synchronizedMap(new HashMap<String, RequestFuture>());
private final Map<String, Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>> myPreloadedBuilds =
Collections.synchronizedMap(new HashMap<String, Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>>());
private final Map<String, Future<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>>> myPreloadedBuilds =
Collections.synchronizedMap(new HashMap<String, Future<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>>>());
private final BuildProcessClasspathManager myClasspathManager = new BuildProcessClasspathManager();
private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
private final Map<String, ProjectData> myProjectDataMap = Collections.synchronizedMap(new HashMap<String, ProjectData>());
@@ -447,7 +447,7 @@ public class BuildManager implements ApplicationComponent{
}
final List<TargetTypeBuildScope> scopes = CmdlineProtoUtil.createAllModulesScopes(false);
final AutoMakeMessageHandler handler = new AutoMakeMessageHandler(project);
final BasicFuture future = scheduleBuild(
final TaskFuture future = scheduleBuild(
project, false, true, false, scopes, Collections.<String>emptyList(), Collections.<String, String>emptyMap(), handler
);
if (future != null) {
@@ -526,12 +526,12 @@ public class BuildManager implements ApplicationComponent{
return false;
}
public Collection<BasicFuture> cancelAutoMakeTasks(Project project) {
final Collection<BasicFuture> futures = new SmartList<BasicFuture>();
public Collection<TaskFuture> cancelAutoMakeTasks(Project project) {
final Collection<TaskFuture> futures = new SmartList<TaskFuture>();
synchronized (myAutomakeFutures) {
for (Map.Entry<BasicFuture, Project> entry : myAutomakeFutures.entrySet()) {
for (Map.Entry<TaskFuture, Project> entry : myAutomakeFutures.entrySet()) {
if (entry.getValue().equals(project)) {
final BasicFuture future = entry.getKey();
final TaskFuture future = entry.getKey();
future.cancel(false);
futures.add(future);
}
@@ -542,15 +542,15 @@ public class BuildManager implements ApplicationComponent{
private void cancelPreloadedBuilds(Project project) {
final String projectPath = getProjectPath(project);
final Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> pair = myPreloadedBuilds.remove(projectPath);
if (pair != null) {
final RequestFuture<PreloadedProcessMessageHandler> future = pair.first;
myMessageDispatcher.cancelSession(future.getRequestID());
runCommand(new Runnable() {
@Override
public void run() {
runCommand(new Runnable() {
@Override
public void run() {
Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> pair = takePreloadedProcess(projectPath);
if (pair != null) {
final RequestFuture<PreloadedProcessMessageHandler> future = pair.first;
myMessageDispatcher.cancelSession(future.getRequestID());
// waiting for preloaded process from project's task queue guarantees no build is started for this project
// until this one gracefully exits and closes all its storages
// until this one gracefully exits and closes all its storages
getProjectData(projectPath).taskQueue.submit(new Runnable() {
@Override
public void run() {
@@ -558,207 +558,221 @@ public class BuildManager implements ApplicationComponent{
}
});
}
});
}
}
});
}
@Nullable
public BasicFuture scheduleBuild(
private Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> takePreloadedProcess(String projectPath) {
Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> result;
final Future<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>> preloadProgress = myPreloadedBuilds.remove(projectPath);
try {
result = preloadProgress != null ? preloadProgress.get() : null;
}
catch (Throwable e) {
LOG.info(e);
result = null;
}
return result;
}
@Nullable
public TaskFuture scheduleBuild(
final Project project, final boolean isRebuild, final boolean isMake,
final boolean onlyCheckUpToDate, final List<TargetTypeBuildScope> scopes,
final Collection<String> paths,
final Map<String, String> userData, final DefaultMessageHandler messageHandler) {
final String projectPath = getProjectPath(project);
final Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> preloaded = myPreloadedBuilds.remove(projectPath);
final RequestFuture<PreloadedProcessMessageHandler> preloadedFuture = preloaded != null? preloaded.first : null;
final boolean usingPreloadedProcess = preloadedFuture != null;
final UUID sessionId;
final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, messageHandler instanceof AutoMakeMessageHandler);
if (usingPreloadedProcess) {
LOG.info("Using preloaded build process to compile " + projectPath);
sessionId = preloadedFuture.getRequestID();
preloadedFuture.getMessageHandler().setDelegateHandler(handler);
}
else {
sessionId = UUID.randomUUID();
}
try {
ensureListening();
}
catch (Exception e) {
final UUID sessionId = UUID.randomUUID(); // the actual session did not start, use random UUID
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null));
handler.sessionTerminated(sessionId);
return null;
}
try {
final RequestFuture<? extends BuilderMessageHandler> future = usingPreloadedProcess? preloadedFuture : new RequestFuture<BuilderMessageHandler>(handler, sessionId, new RequestFuture.CancelAction<BuilderMessageHandler>() {
@Override
public void cancel(RequestFuture<BuilderMessageHandler> future) throws Exception {
myMessageDispatcher.cancelSession(future.getRequestID());
final DelegateFuture<BuilderMessageHandler> _future = new DelegateFuture<BuilderMessageHandler>();
// by using the same queue that processes events we ensure that
// the build will be aware of all events that have happened before this request
runCommand(new Runnable() {
@Override
public void run() {
final Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> preloaded = takePreloadedProcess(projectPath);
final RequestFuture<PreloadedProcessMessageHandler> preloadedFuture = preloaded != null? preloaded.first : null;
final boolean usingPreloadedProcess = preloadedFuture != null;
final UUID sessionId;
if (usingPreloadedProcess) {
LOG.info("Using preloaded build process to compile " + projectPath);
sessionId = preloadedFuture.getRequestID();
preloadedFuture.getMessageHandler().setDelegateHandler(handler);
}
else {
sessionId = UUID.randomUUID();
}
});
// by using the same queue that processes events we ensure that
// the build will be aware of all events that have happened before this request
runCommand(new Runnable() {
@Override
public void run() {
if (!usingPreloadedProcess && (future.isCancelled() || project.isDisposed())) {
// in case of preloaded process the process was already running, so the handler will be notified upon process termination
handler.sessionTerminated(sessionId);
future.setDone();
return;
}
final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals =
CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder().setGlobalOptionsPath(PathManager.getOptionsPath()).build();
CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges;
final SequentialTaskExecutor projectTaskQueue;
synchronized (myProjectDataMap) {
final ProjectData data = getProjectData(projectPath);
if (isRebuild) {
data.dropChanges();
}
if (IS_UNIT_TEST_MODE) {
LOG.info("Scheduling build for " +
projectPath +
"; CHANGED: " +
new HashSet<String>(convertToStringPaths(data.myChanged)) +
"; DELETED: " +
new HashSet<String>(convertToStringPaths(data.myDeleted)));
}
currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent();
projectTaskQueue = data.taskQueue;
final RequestFuture<? extends BuilderMessageHandler> future = usingPreloadedProcess? preloadedFuture : new RequestFuture<BuilderMessageHandler>(handler, sessionId, new RequestFuture.CancelAction<BuilderMessageHandler>() {
@Override
public void cancel(RequestFuture<BuilderMessageHandler> future) throws Exception {
myMessageDispatcher.cancelSession(future.getRequestID());
}
});
_future.setDelegate(future);
final CmdlineRemoteProto.Message.ControllerMessage params;
if (!usingPreloadedProcess && (future.isCancelled() || project.isDisposed())) {
// in case of preloaded process the process was already running, so the handler will be notified upon process termination
handler.sessionTerminated(sessionId);
((BasicFuture)future).setDone();
return;
}
final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals =
CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder().setGlobalOptionsPath(PathManager.getOptionsPath()).build();
CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges;
final SequentialTaskExecutor projectTaskQueue;
synchronized (myProjectDataMap) {
final ProjectData data = getProjectData(projectPath);
if (isRebuild) {
params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, Collections.<String>emptyList(), userData, globals, null);
data.dropChanges();
}
else if (onlyCheckUpToDate) {
params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges);
}
else {
params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.<String>emptyList() : paths, userData, globals, currentFSChanges);
}
if (!usingPreloadedProcess) {
myMessageDispatcher.registerBuildMessageHandler(future, params);
if (IS_UNIT_TEST_MODE) {
LOG.info("Scheduling build for " +
projectPath +
"; CHANGED: " +
new HashSet<String>(convertToStringPaths(data.myChanged)) +
"; DELETED: " +
new HashSet<String>(convertToStringPaths(data.myDeleted)));
}
currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent();
projectTaskQueue = data.taskQueue;
}
try {
projectTaskQueue.submit(new Runnable() {
@Override
public void run() {
Throwable execFailure = null;
try {
if (project.isDisposed()) {
if (usingPreloadedProcess) {
future.cancel(true);
}
else {
return;
}
}
myBuildsInProgress.put(projectPath, future);
final OSProcessHandler processHandler;
final StringBuilder errorsOnLaunch = new StringBuilder();
final CmdlineRemoteProto.Message.ControllerMessage params;
if (isRebuild) {
params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, Collections.<String>emptyList(), userData, globals, null);
}
else if (onlyCheckUpToDate) {
params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges);
}
else {
params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.<String>emptyList() : paths, userData, globals, currentFSChanges);
}
if (!usingPreloadedProcess) {
myMessageDispatcher.registerBuildMessageHandler(future, params);
}
try {
projectTaskQueue.submit(new Runnable() {
@Override
public void run() {
Throwable execFailure = null;
try {
if (project.isDisposed()) {
if (usingPreloadedProcess) {
final boolean paramsSent = myMessageDispatcher.sendBuildParameters(future.getRequestID(), params);
if (!paramsSent) {
myMessageDispatcher.cancelSession(future.getRequestID());
}
processHandler = preloaded.second;
future.cancel(true);
}
else {
processHandler = launchBuildProcess(project, myListenPort, sessionId, false);
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (ProcessOutputTypes.STDERR.equals(outputType)) {
if (errorsOnLaunch.length() < 1024) {
final String text = event.getText();
if (!StringUtil.isEmptyOrSpaces(text)) {
errorsOnLaunch.append(text);
}
return;
}
}
myBuildsInProgress.put(projectPath, future);
final OSProcessHandler processHandler;
final StringBuilder errorsOnLaunch = new StringBuilder();
if (usingPreloadedProcess) {
final boolean paramsSent = myMessageDispatcher.sendBuildParameters(future.getRequestID(), params);
if (!paramsSent) {
myMessageDispatcher.cancelSession(future.getRequestID());
}
processHandler = preloaded.second;
}
else {
processHandler = launchBuildProcess(project, myListenPort, sessionId, false);
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (ProcessOutputTypes.STDERR.equals(outputType)) {
if (errorsOnLaunch.length() < 1024) {
final String text = event.getText();
if (!StringUtil.isEmptyOrSpaces(text)) {
errorsOnLaunch.append(text);
}
}
}
});
processHandler.startNotify();
}
final boolean terminated = processHandler.waitFor();
if (terminated) {
final int exitValue = processHandler.getProcess().exitValue();
if (exitValue != 0) {
final StringBuilder msg = new StringBuilder();
msg.append("Abnormal build process termination: ");
if (errorsOnLaunch.length() > 0) {
msg.append("\n").append(errorsOnLaunch);
}
else {
msg.append("unknown error");
}
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null));
}
}
else {
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null));
});
processHandler.startNotify();
}
final boolean terminated = processHandler.waitFor();
if (terminated) {
final int exitValue = processHandler.getProcess().exitValue();
if (exitValue != 0) {
final StringBuilder msg = new StringBuilder();
msg.append("Abnormal build process termination: ");
if (errorsOnLaunch.length() > 0) {
msg.append("\n").append(errorsOnLaunch);
}
else {
msg.append("unknown error");
}
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null));
}
}
catch (Throwable e) {
execFailure = e;
}
finally {
myBuildsInProgress.remove(projectPath);
if (myMessageDispatcher.getAssociatedChannel(sessionId) == null) {
// either the connection has never been established (process not started or execution failed), or no messages were sent from the launched process.
// in this case the session cannot be unregistered by the message dispatcher
final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
if (unregistered != null) {
if (execFailure != null) {
unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(execFailure.getMessage(), execFailure));
}
unregistered.sessionTerminated(sessionId);
}
}
if (Registry.is("compiler.process.preload") && !project.isDisposed()) {
try {
final Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> pair = launchPreloadedBuildProcess(project);
myPreloadedBuilds.put(projectPath, pair);
}
catch (Exception e) {
LOG.info("Error pre-loading build process for project " + projectPath, e);
}
}
else {
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null));
}
}
});
}
catch (Throwable e) {
final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
if (unregistered != null) {
unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
unregistered.sessionTerminated(sessionId);
catch (Throwable e) {
execFailure = e;
}
finally {
myBuildsInProgress.remove(projectPath);
if (myMessageDispatcher.getAssociatedChannel(sessionId) == null) {
// either the connection has never been established (process not started or execution failed), or no messages were sent from the launched process.
// in this case the session cannot be unregistered by the message dispatcher
final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
if (unregistered != null) {
if (execFailure != null) {
unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(execFailure.getMessage(), execFailure));
}
unregistered.sessionTerminated(sessionId);
}
}
if (Registry.is("compiler.process.preload") && !project.isDisposed()) {
runCommand(new Runnable() {
public void run() {
try {
final Future<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>> preloadResult = launchPreloadedBuildProcess(project, projectTaskQueue);
myPreloadedBuilds.put(projectPath, preloadResult);
}
catch (Exception e) {
LOG.info("Error pre-loading build process for project " + projectPath, e);
}
}
});
}
}
}
});
}
catch (Throwable e) {
final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
if (unregistered != null) {
unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
unregistered.sessionTerminated(sessionId);
}
}
});
}
});
return future;
}
catch (Throwable e) {
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
handler.sessionTerminated(sessionId);
}
return null;
return _future;
}
@NotNull
@@ -798,37 +812,42 @@ public class BuildManager implements ApplicationComponent{
return "com.intellij.compiler.server.BuildManager";
}
private Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> launchPreloadedBuildProcess(final Project project) throws Exception {
private Future<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>> launchPreloadedBuildProcess(final Project project, SequentialTaskExecutor projectTaskQueue) throws Exception {
ensureListening();
final RequestFuture<PreloadedProcessMessageHandler> future = new RequestFuture<PreloadedProcessMessageHandler>(new PreloadedProcessMessageHandler(project), UUID.randomUUID(), new RequestFuture.CancelAction<PreloadedProcessMessageHandler>() {
@Override
public void cancel(RequestFuture<PreloadedProcessMessageHandler> future) throws Exception {
myMessageDispatcher.cancelSession(future.getRequestID());
// launching build process from projectTaskQueue ensures that no other build process for this project is currently running
return projectTaskQueue.submit(new Callable<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>>() {
public Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> call() throws Exception {
final RequestFuture<PreloadedProcessMessageHandler> future = new RequestFuture<PreloadedProcessMessageHandler>(new PreloadedProcessMessageHandler(project), UUID.randomUUID(), new RequestFuture.CancelAction<PreloadedProcessMessageHandler>() {
@Override
public void cancel(RequestFuture<PreloadedProcessMessageHandler> future) throws Exception {
myMessageDispatcher.cancelSession(future.getRequestID());
}
});
try {
myMessageDispatcher.registerBuildMessageHandler(future, null);
final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, future.getRequestID(), true);
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (ProcessOutputTypes.STDERR.equals(outputType)) {
final String text = event.getText();
if (!StringUtil.isEmptyOrSpaces(text)) {
LOG.info("PRELOADED_BUILD_PROCESS: " + text);
}
}
}
});
processHandler.startNotify();
return Pair.create(future, processHandler);
}
catch (ExecutionException e) {
myMessageDispatcher.unregisterBuildMessageHandler(future.getRequestID());
throw e;
}
}
});
myMessageDispatcher.registerBuildMessageHandler(future, null);
try {
final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, future.getRequestID(), true);
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (ProcessOutputTypes.STDERR.equals(outputType)) {
final String text = event.getText();
if (!StringUtil.isEmptyOrSpaces(text)) {
LOG.info("PRELOADED_BUILD_PROCESS: " + text);
}
}
}
});
processHandler.startNotify();
return Pair.create(future, processHandler);
}
catch (ExecutionException e) {
myMessageDispatcher.unregisterBuildMessageHandler(future.getRequestID());
throw e;
}
}
private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId, boolean requestProjectPreload) throws ExecutionException {
@@ -1300,7 +1319,7 @@ public class BuildManager implements ApplicationComponent{
@Override
public void projectClosing(Project project) {
cancelPreloadedBuilds(project);
for (BasicFuture future : cancelAutoMakeTasks(project)) {
for (TaskFuture future : cancelAutoMakeTasks(project)) {
future.waitFor(500, TimeUnit.MILLISECONDS);
}
}
@@ -1460,5 +1479,88 @@ public class BuildManager implements ApplicationComponent{
return "/";
}
}
private static final class DelegateFuture<T> implements TaskFuture<T> {
@Nullable
private TaskFuture<? extends T> myDelegate;
private Boolean myRequestedCancelState = null;
@NotNull
public synchronized TaskFuture<? extends T> getDelegate() {
TaskFuture<? extends T> delegate = myDelegate;
while (delegate == null) {
try {
wait();
}
catch (InterruptedException ignored) {
}
delegate = myDelegate;
}
return delegate;
}
public synchronized boolean setDelegate(@NotNull TaskFuture<? extends T> delegate) {
if (myDelegate == null) {
try {
myDelegate = delegate;
if (myRequestedCancelState != null) {
myDelegate.cancel(myRequestedCancelState);
}
}
finally {
notifyAll();
}
return true;
}
return false;
}
public synchronized boolean cancel(boolean mayInterruptIfRunning) {
final TaskFuture<? extends T> delegate = myDelegate;
if (delegate == null) {
myRequestedCancelState = mayInterruptIfRunning;
return true;
}
return delegate.cancel(mayInterruptIfRunning);
}
public void waitFor() {
getDelegate().waitFor();
}
public boolean waitFor(long timeout, TimeUnit unit) {
return getDelegate().waitFor(timeout, unit);
}
public boolean isCancelled() {
final TaskFuture<? extends T> delegate;
synchronized (this) {
delegate = myDelegate;
if (delegate == null) {
return myRequestedCancelState != null;
}
}
return delegate.isCancelled();
}
public boolean isDone() {
final TaskFuture<? extends T> delegate;
synchronized (this) {
delegate = myDelegate;
if (delegate == null) {
return false;
}
}
return delegate.isDone();
}
public T get() throws InterruptedException, java.util.concurrent.ExecutionException {
return getDelegate().get();
}
public T get(long timeout, TimeUnit unit) throws InterruptedException, java.util.concurrent.ExecutionException, TimeoutException {
return getDelegate().get(timeout, unit);
}
}
}
@@ -50,7 +50,7 @@ public class JavaReferringObjectsValue extends JavaValue {
}
public JavaReferringObjectsValue(@NotNull JavaValue javaValue, boolean isField) {
super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), null, false);
super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), javaValue.getNodeManager(), false);
myIsField = isField;
}
@@ -84,7 +84,7 @@ public class JavaReferringObjectsValue extends JavaValue {
return reference;
}
};
children.add(new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, true));
children.add(new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), getNodeManager(), true));
i++;
}
else {
@@ -109,7 +109,7 @@ public class JavaReferringObjectsValue extends JavaValue {
return null;
}
};
children.add("Referrer " + i++, new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, false));
children.add("Referrer " + i++, new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), getNodeManager(), false));
}
}
@@ -168,4 +168,10 @@ public class JavaReferringObjectsValue extends JavaValue {
}
return null;
}
@Nullable
@Override
public XValueModifier getModifier() {
return null;
}
}
@@ -70,6 +70,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
private final EvaluationContextImpl myEvaluationContext;
private final NodeManagerImpl myNodeManager;
private final boolean myContextSet;
private final DebuggerManagerThreadImpl myDebuggerManagerThread;
protected JavaValue(JavaValue parent,
@NotNull ValueDescriptorImpl valueDescriptor,
@@ -82,6 +83,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
myEvaluationContext = evaluationContext;
myNodeManager = nodeManager;
myContextSet = contextSet;
myDebuggerManagerThread = evaluationContext.getDebugProcess().getManagerThread();
}
static JavaValue create(JavaValue parent,
@@ -113,6 +115,10 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
return myEvaluationContext;
}
public NodeManagerImpl getNodeManager() {
return myNodeManager;
}
@Override
public void computePresentation(@NotNull final XValueNode node, @NotNull XValuePlace place) {
final SuspendContextImpl suspendContext = myEvaluationContext.getSuspendContext();
@@ -349,7 +355,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
}
boolean scheduleCommand(SuspendContextCommandImpl command) {
return scheduleCommand(myEvaluationContext, null, command);
if (myEvaluationContext.getSuspendContext().isResumed()) {
return false;
}
myDebuggerManagerThread.schedule(command);
return true;
}
protected static boolean scheduleCommand(EvaluationContextImpl evaluationContext,
@@ -486,6 +496,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
@Nullable
@Override
public XReferrersProvider getReferrersProvider() {
if (myEvaluationContext.getSuspendContext().isResumed()) return null;
return new XReferrersProvider() {
@Override
public XValue getReferringObjectsValue() {
@@ -497,16 +508,15 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
@Nullable
@Override
public XInstanceEvaluator getInstanceEvaluator() {
final DebugProcessImpl process = myEvaluationContext.getDebugProcess();
return new XInstanceEvaluator() {
@Override
public void evaluate(@NotNull final XDebuggerEvaluator.XEvaluationCallback callback, @NotNull final XStackFrame frame) {
process.getManagerThread().schedule(new DebuggerCommandImpl() {
myDebuggerManagerThread.schedule(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
ValueDescriptorImpl inspectDescriptor = myValueDescriptor;
if (myValueDescriptor instanceof WatchItemDescriptor) {
inspectDescriptor = (ValueDescriptorImpl) ((WatchItemDescriptor) myValueDescriptor).getModifier().getInspectItem(getProject());
inspectDescriptor = (ValueDescriptorImpl)((WatchItemDescriptor)myValueDescriptor).getModifier().getInspectItem(getProject());
}
EvaluationContextImpl evaluationContext = ((JavaStackFrame)frame).getFrameDebuggerContext().createEvaluationContext();
if (evaluationContext != null) {
@@ -15,14 +15,17 @@
*/
package org.jetbrains.jps.api;
import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Eugene Zhuravlev
* Date: 5/3/12
*/
public class BasicFuture<T> implements Future<T> {
public class BasicFuture<T> implements TaskFuture<T> {
protected final Semaphore mySemaphore = new Semaphore(1);
private final AtomicBoolean myDone = new AtomicBoolean(false);
private final AtomicBoolean myCanceledState = new AtomicBoolean(false);
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jps.api;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public interface TaskFuture<T> extends Future<T> {
void waitFor();
boolean waitFor(long timeout, TimeUnit unit);
}
@@ -16,6 +16,7 @@
package org.jetbrains.jps.cmdline;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import io.netty.bootstrap.Bootstrap;
@@ -124,9 +125,12 @@ public class BuildMain {
final String projectPathToPreload = System.getProperty(PRELOAD_PROJECT_PATH, null);
final String globalsPathToPreload = System.getProperty(PRELOAD_CONFIG_PATH, null);
if (projectPathToPreload != null && globalsPathToPreload != null) {
final long preloadStart = System.currentTimeMillis();
final PreloadedData data = new PreloadedData();
ourPreloadedData = data;
try {
FileSystemUtil.getAttributes(projectPathToPreload); // this will pre-load all FS optimizations
final BuildRunner runner = new BuildRunner(new JpsModelLoaderImpl(projectPathToPreload, globalsPathToPreload, null));
data.setRunner(runner);
@@ -162,10 +166,11 @@ public class BuildMain {
LOG.info("Error pre-loading FS state", e);
fsState.clearAll();
}
LOG.info("Pre-loaded project model in " + (System.currentTimeMillis() - preloadStart) + " ms");
}
catch (Throwable e) {
LOG.info("Failed to pre-load project " + projectPathToPreload, e);
// just failed to preload the project, the situation will be handled later, when real build starts
// just failed to preload the project, the situation will be handled later, when real build starts
}
}
else if (projectPathToPreload != null || globalsPathToPreload != null){
@@ -168,7 +168,16 @@ public class JavacMain {
diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
}
catch (CompilationCanceledException ignored) {
diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled"));
handleCancelException(diagnosticConsumer);
}
catch (RuntimeException e) {
final Throwable cause = e.getCause();
if (cause instanceof CompilationCanceledException) {
handleCancelException(diagnosticConsumer);
}
else {
throw e;
}
}
finally {
fileManager.close();
@@ -179,6 +188,10 @@ public class JavacMain {
return false;
}
private static void handleCancelException(DiagnosticOutputConsumer diagnosticConsumer) {
diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled"));
}
private static List<JavaSourceTransformer> getSourceTransformers() {
final Class<JavaSourceTransformer> transformerClass = JavaSourceTransformer.class;
final ServiceLoader<JavaSourceTransformer> loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader());
@@ -15,6 +15,7 @@
*/
package org.jetbrains.jps.model.serialization;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -30,6 +31,8 @@ import java.io.IOException;
* @author nik
*/
public abstract class JpsLoaderBase {
private static final Logger LOG = Logger.getInstance(JpsLoaderBase.class);
private static final int MAX_ATTEMPTS = 5;
private final JpsMacroExpander myMacroExpander;
protected JpsLoaderBase(JpsMacroExpander macroExpander) {
@@ -66,7 +69,7 @@ public abstract class JpsLoaderBase {
protected static Element loadRootElement(final File file, final JpsMacroExpander macroExpander) {
try {
final Element element = JDOMUtil.loadDocument(file).getRootElement();
final Element element = tryLoadRootElement(file);
macroExpander.substitute(element, SystemInfo.isFileSystemCaseSensitive);
return element;
}
@@ -78,6 +81,24 @@ public abstract class JpsLoaderBase {
}
}
private static Element tryLoadRootElement(File file) throws IOException, JDOMException {
for (int i = 0; i < MAX_ATTEMPTS - 1; i++) {
try {
return JDOMUtil.loadDocument(file).getRootElement();
}
catch (Exception e) {
LOG.info("Loading attempt #" + i + " failed", e);
}
//most likely configuration file is being written by IDE so we'll wait a little
try {
//noinspection BusyWait
Thread.sleep(300);
}
catch (InterruptedException ignored) { }
}
return JDOMUtil.loadDocument(file).getRootElement();
}
protected static boolean isXmlFile(File file) {
return file.isFile() && FileUtilRt.extensionEquals(file.getName(), "xml");
}
@@ -89,6 +89,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private final ASTNode myOriginalTree;
private final MyTreeStructure myParentLightTree;
private final int myOffset;
private static TokenSet ourAnyLanguageWhitespaceTokens = TokenSet.EMPTY;
@@ -132,7 +133,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@Nullable ASTNode originalTree,
@Nullable MyTreeStructure parentLightTree) {
this(project, containingFile, parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), lexer, charTable, text,
originalTree, parentLightTree);
originalTree, parentLightTree, 0);
}
public PsiBuilderImpl(Project project,
@@ -144,6 +145,19 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@NotNull final CharSequence text,
@Nullable ASTNode originalTree,
@Nullable MyTreeStructure parentLightTree) {
this(project, containingFile, whiteSpaces, comments, lexer, charTable, text, originalTree, parentLightTree, 0);
}
private PsiBuilderImpl(Project project,
PsiFile containingFile,
@NotNull TokenSet whiteSpaces,
@NotNull TokenSet comments,
@NotNull Lexer lexer,
CharTable charTable,
@NotNull final CharSequence text,
@Nullable ASTNode originalTree,
@Nullable MyTreeStructure parentLightTree,
int offset) {
myProject = project;
myFile = containingFile;
@@ -156,6 +170,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
myCharTable = charTable;
myOriginalTree = originalTree;
myParentLightTree = parentLightTree;
myOffset = offset;
cacheLexemes();
}
@@ -174,8 +189,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@NotNull final Lexer lexer,
@NotNull final LighterLazyParseableNode chameleon,
@NotNull final CharSequence text) {
this(project, chameleon.getContainingFile(), parserDefinition, lexer, chameleon.getCharTable(), text,
null, ((LazyParseableToken)chameleon).myParent);
this(project, chameleon.getContainingFile(), parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), lexer,
chameleon.getCharTable(), text, null, ((LazyParseableToken)chameleon).myParent, chameleon.getStartOffset());
}
private void cacheLexemes() {
@@ -335,12 +350,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@Override
public int getStartOffset() {
return myBuilder.myLexStarts[myLexemeIndex];
return myBuilder.myLexStarts[myLexemeIndex] + myBuilder.myOffset;
}
@Override
public int getEndOffset() {
return myBuilder.myLexStarts[myDoneMarker.myLexemeIndex];
return myBuilder.myLexStarts[myDoneMarker.myLexemeIndex] + myBuilder.myOffset;
}
@Override
@@ -487,12 +502,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@Override
public int getEndOffset() {
return myTokenEnd;
return myTokenEnd + myBuilder.myOffset;
}
@Override
public int getStartOffset() {
return myTokenStart;
return myTokenStart + myBuilder.myOffset;
}
public CharSequence getText() {
@@ -636,12 +651,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@Override
public int getEndOffset() {
return myBuilder.myLexStarts[myLexemeIndex];
return myBuilder.myLexStarts[myLexemeIndex] + myBuilder.myOffset;
}
@Override
public int getStartOffset() {
return myBuilder.myLexStarts[myLexemeIndex];
return myBuilder.myLexStarts[myLexemeIndex] + myBuilder.myOffset;
}
@Override
@@ -1474,6 +1489,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private final LimitedPool<Token> myPool;
private final LimitedPool<LazyParseableToken> myLazyPool;
private final StartMarker myRoot;
private final int myOffset;
public MyTreeStructure(@NotNull StartMarker root, @Nullable final MyTreeStructure parentTree) {
if (parentTree == null) {
@@ -1499,10 +1515,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return new LazyParseableToken();
}
});
myOffset = 0;
}
else {
myPool = parentTree.myPool;
myLazyPool = parentTree.myLazyPool;
myOffset = parentTree.getRoot().getStartOffset();
}
myRoot = root;
}
@@ -55,7 +55,7 @@ import java.util.Map;
public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayList> implements PsiDependentIndex {
static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.duplicates.online.calculation",
isEnabledByDefault());
static boolean ourEnabledLightProfiles = false;
static boolean ourEnabledLightProfiles = true;
private static boolean isEnabledByDefault() {
Application application = ApplicationManager.getApplication();
@@ -3,10 +3,16 @@ package com.intellij.dupLocator.index;
import com.intellij.codeInspection.*;
import com.intellij.dupLocator.DuplicatesProfile;
import com.intellij.dupLocator.DuplocatorState;
import com.intellij.dupLocator.LightDuplicateProfile;
import com.intellij.dupLocator.treeHash.FragmentsCollector;
import com.intellij.dupLocator.util.PsiFragment;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.lang.TreeBackedLighterAST;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileWithId;
@@ -35,94 +41,126 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
final DuplicatesProfile profile = DuplicatesIndex.findDuplicatesProfile(psiFile.getFileType());
if (profile == null) return ProblemDescriptor.EMPTY_ARRAY;
final DuplocatorState state = profile.getDuplocatorState(psiFile.getLanguage());
final SmartList<ProblemDescriptor> descriptors = new SmartList<ProblemDescriptor>();
final Ref<DuplicatedCodeProcessor> myProcessorRef = new Ref<DuplicatedCodeProcessor>();
final TreeMap<Integer, TextRange> reportedRanges = new TreeMap<Integer, TextRange>();
final TIntObjectHashMap<VirtualFile> reportedFiles = new TIntObjectHashMap<VirtualFile>();
final TIntObjectHashMap<PsiElement> reportedPsi = new TIntObjectHashMap<PsiElement>();
final TIntIntHashMap reportedOffsetInOtherFiles = new TIntIntHashMap();
final TIntIntHashMap fragmentSize = new TIntIntHashMap();
if (profile instanceof LightDuplicateProfile && DuplicatesIndex.ourEnabledLightProfiles) {
profile.createVisitor(new FragmentsCollector() {
@Override
public void add(int hash, final int cost, @Nullable final PsiFragment frag) {
if (!DuplicatesIndex.isIndexedFragment(frag, cost, profile, state)) {
return;
((LightDuplicateProfile)profile).process(psiFile, new LightDuplicateProfile.Callback() {
DuplicatedCodeProcessor<LighterASTNode> myProcessor;
@Override
public void process(final LighterAST ast, final LighterASTNode node, int hash) {
class LightDuplicatedCodeProcessor extends DuplicatedCodeProcessor<LighterASTNode> {
LightDuplicatedCodeProcessor(VirtualFile file, Project project) {
super(file, project);
}
@Override
protected TextRange getRangeInElement(LighterASTNode node) {
return null;
}
@Override
protected PsiElement getPsi(LighterASTNode node) {
return ((TreeBackedLighterAST)ast).unwrap(node).getPsi();
}
@Override
protected int getStartOffset(LighterASTNode node) {
return node.getStartOffset();
}
@Override
protected int getEndOffset(LighterASTNode node) {
return node.getEndOffset();
}
}
if (myProcessor == null) {
myProcessor = new LightDuplicatedCodeProcessor(virtualFile, psiFile.getProject());
myProcessorRef.set(myProcessor);
}
myProcessor.process(hash, node);
}
});
} else {
final DuplocatorState state = profile.getDuplocatorState(psiFile.getLanguage());
profile.createVisitor(new FragmentsCollector() {
DuplicatedCodeProcessor<PsiFragment> myProcessor;
@Override
public void add(int hash, final int cost, @Nullable final PsiFragment frag) {
if (!DuplicatesIndex.isIndexedFragment(frag, cost, profile, state)) {
return;
}
ProgressManager.checkCanceled();
FileBasedIndex.getInstance().processValues(DuplicatesIndex.NAME, hash, null, new FileBasedIndex.ValueProcessor<TIntArrayList>() {
final ProjectFileIndex myProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(psiFile.getProject());
@Override
public boolean process(final VirtualFile file, final TIntArrayList list) {
for(int i = 0, len = list.size(); i < len; ++i) {
ProgressManager.checkCanceled();
class OldDuplicatedCodeProcessor extends DuplicatedCodeProcessor<PsiFragment> {
int value = list.getQuick(i);
OldDuplicatedCodeProcessor(VirtualFile file, Project project) {
super(file, project);
}
if (myProjectFileIndex.isInSource(virtualFile) && !myProjectFileIndex.isInSource(file)) return true;
if (!myProjectFileIndex.isInSource(virtualFile) && myProjectFileIndex.isInSource(file)) return true;
final int startOffset = frag.getStartOffset();
final int endOffset = frag.getEndOffset();
if (file.equals(virtualFile) && value >= startOffset && value < endOffset) continue;
PsiElement[] elements = frag.getElements();
PsiElement target = elements[0];
@Override
protected TextRange getRangeInElement(PsiFragment node) {
PsiElement[] elements = node.getElements();
TextRange rangeInElement = null;
if (elements.length > 1) {
PsiElement firstElement = elements[0];
target = firstElement.getParent();
PsiElement lastElement = elements[elements.length - 1];
rangeInElement = new TextRange(
elements[0].getStartOffsetInParent(),
lastElement.getStartOffsetInParent() + lastElement.getTextLength()
);
}
return rangeInElement;
}
Integer fragmentStartOffsetInteger = startOffset;
SortedMap<Integer,TextRange> map = reportedRanges.subMap(fragmentStartOffsetInteger, endOffset);
int newFragmentSize = !map.isEmpty() ? 0:1;
@Override
protected PsiElement getPsi(PsiFragment node) {
PsiElement[] elements = node.getElements();
Iterator<Integer> iterator = map.keySet().iterator();
while(iterator.hasNext()) {
Integer next = iterator.next();
iterator.remove();
reportedFiles.remove(next);
reportedOffsetInOtherFiles.remove(next);
reportedPsi.remove(next);
newFragmentSize += fragmentSize.remove(next);
}
return elements.length > 1 ? elements[0].getParent() : elements[0];
}
reportedRanges.put(fragmentStartOffsetInteger, rangeInElement);
reportedFiles.put(fragmentStartOffsetInteger, file);
reportedOffsetInOtherFiles.put(fragmentStartOffsetInteger, value);
reportedPsi.put(fragmentStartOffsetInteger, target);
fragmentSize.put(fragmentStartOffsetInteger, newFragmentSize);
@Override
protected int getStartOffset(PsiFragment node) {
return node.getStartOffset();
}
return false;
@Override
protected int getEndOffset(PsiFragment node) {
return node.getEndOffset();
}
return true;
}
}, GlobalSearchScope.projectScope(psiFile.getProject()));
if (myProcessor == null) {
myProcessor = new OldDuplicatedCodeProcessor(virtualFile, psiFile.getProject());
myProcessorRef.set(myProcessor);
}
myProcessor.process(hash, frag);
}
}, true).visitNode(psiFile);
}
DuplicatedCodeProcessor<?> processor = myProcessorRef.get();
final SmartList<ProblemDescriptor> descriptors = new SmartList<ProblemDescriptor>();
if (processor != null) {
for(Map.Entry<Integer, TextRange> entry:processor.reportedRanges.entrySet()) {
final Integer offset = entry.getKey();
// todo 3 statements constant
if (processor.fragmentSize.get(offset) < 3) continue;
final VirtualFile file = processor.reportedFiles.get(offset);
String message = "Found duplicated code in " + file.getPath();
PsiElement targetElement = processor.reportedPsi.get(offset);
TextRange rangeInElement = entry.getValue();
final int offsetInOtherFile = processor.reportedOffsetInOtherFiles.get(offset);
LocalQuickFix fix = createNavigateToDupeFix(file, offsetInOtherFile);
ProblemDescriptor descriptor = manager
.createProblemDescriptor(targetElement, rangeInElement, message, ProblemHighlightType.WEAK_WARNING, isOnTheFly, fix);
descriptors.add(descriptor);
}
}, true).visitNode(psiFile);
for(Map.Entry<Integer, TextRange> entry:reportedRanges.entrySet()) {
final Integer offset = entry.getKey();
// todo 3 statements constant
if (fragmentSize.get(offset) < 3) continue;
final VirtualFile file = reportedFiles.get(offset);
String message = "Found duplicated code in " + file.getPath();
PsiElement targetElement = reportedPsi.get(offset);
TextRange rangeInElement = entry.getValue();
final int offsetInOtherFile = reportedOffsetInOtherFiles.get(offset);
LocalQuickFix fix = createNavigateToDupeFix(file, offsetInOtherFile);
ProblemDescriptor descriptor = manager
.createProblemDescriptor(targetElement, rangeInElement, message, ProblemHighlightType.WEAK_WARNING, isOnTheFly, fix);
descriptors.add(descriptor);
}
return descriptors.isEmpty() ? null : descriptors.toArray(new ProblemDescriptor[descriptors.size()]);
@@ -131,4 +169,75 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
protected LocalQuickFix createNavigateToDupeFix(@NotNull VirtualFile file, int offsetInOtherFile) {
return null;
}
static abstract class DuplicatedCodeProcessor<T> implements FileBasedIndex.ValueProcessor<TIntArrayList> {
final TreeMap<Integer, TextRange> reportedRanges = new TreeMap<Integer, TextRange>();
final TIntObjectHashMap<VirtualFile> reportedFiles = new TIntObjectHashMap<VirtualFile>();
final TIntObjectHashMap<PsiElement> reportedPsi = new TIntObjectHashMap<PsiElement>();
final TIntIntHashMap reportedOffsetInOtherFiles = new TIntIntHashMap();
final TIntIntHashMap fragmentSize = new TIntIntHashMap();
final VirtualFile virtualFile;
final Project project;
final ProjectFileIndex myProjectFileIndex;
T myNode;
DuplicatedCodeProcessor(VirtualFile file, Project project) {
virtualFile = file;
this.project = project;
myProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(project);
}
void process(int hash, T node) {
ProgressManager.checkCanceled();
myNode = node;
FileBasedIndex.getInstance().processValues(DuplicatesIndex.NAME, hash, null, this, GlobalSearchScope.projectScope(project));
}
@Override
public boolean process(VirtualFile file, TIntArrayList list) {
for(int i = 0, len = list.size(); i < len; ++i) {
ProgressManager.checkCanceled();
int value = list.getQuick(i);
if (myProjectFileIndex.isInSource(virtualFile) && !myProjectFileIndex.isInSource(file)) return true;
if (!myProjectFileIndex.isInSource(virtualFile) && myProjectFileIndex.isInSource(file)) return true;
final int startOffset = getStartOffset(myNode);
final int endOffset = getEndOffset(myNode);
if (file.equals(virtualFile) && value >= startOffset && value < endOffset) continue;
PsiElement target = getPsi(myNode);
TextRange rangeInElement = getRangeInElement(myNode);
Integer fragmentStartOffsetInteger = startOffset;
SortedMap<Integer,TextRange> map = reportedRanges.subMap(fragmentStartOffsetInteger, endOffset);
int newFragmentSize = !map.isEmpty() ? 0:1;
Iterator<Integer> iterator = map.keySet().iterator();
while(iterator.hasNext()) {
Integer next = iterator.next();
iterator.remove();
reportedFiles.remove(next);
reportedOffsetInOtherFiles.remove(next);
reportedPsi.remove(next);
newFragmentSize += fragmentSize.remove(next);
}
reportedRanges.put(fragmentStartOffsetInteger, rangeInElement);
reportedFiles.put(fragmentStartOffsetInteger, file);
reportedOffsetInOtherFiles.put(fragmentStartOffsetInteger, value);
reportedPsi.put(fragmentStartOffsetInteger, target);
fragmentSize.put(fragmentStartOffsetInteger, newFragmentSize);
return false;
}
return true;
}
protected abstract TextRange getRangeInElement(T node);
protected abstract PsiElement getPsi(T node);
protected abstract int getStartOffset(T node);
protected abstract int getEndOffset(T node);
}
}
@@ -358,8 +358,10 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
for (final StandardFileType pair : myStandardFileTypes.values()) {
registerFileTypeWithoutNotification(pair.fileType, pair.matchers);
}
for (StandardFileType pair : myStandardFileTypes.values()) {
registerReDetectedMappings(pair);
if (!myUnresolvedMappings.isEmpty()) {
for (StandardFileType pair : myStandardFileTypes.values()) {
registerReDetectedMappings(pair);
}
}
// Resolve unresolved mappings initialized before certain plugin initialized.
for (final StandardFileType pair : myStandardFileTypes.values()) {
@@ -1297,14 +1299,23 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
FileType fileType = pair.fileType;
if (fileType == PlainTextFileType.INSTANCE) return;
for (FileNameMatcher matcher : pair.matchers) {
String typeName = myUnresolvedMappings.get(matcher);
if (typeName != null && !typeName.equals(fileType.getName())) {
Trinity<String, String, Boolean> trinity = myUnresolvedRemovedMappings.get(matcher);
myRemovedMappings.put(matcher, Pair.create(fileType, trinity != null && trinity.third));
registerReDetectedMapping(fileType, matcher);
if (matcher instanceof ExtensionFileNameMatcher) {
// also check exact file name matcher
ExtensionFileNameMatcher extMatcher = (ExtensionFileNameMatcher)matcher;
registerReDetectedMapping(fileType, new ExactFileNameMatcher("." + extMatcher.getExtension()));
}
}
}
private void registerReDetectedMapping(@NotNull FileType fileType, @NotNull FileNameMatcher matcher) {
String typeName = myUnresolvedMappings.get(matcher);
if (typeName != null && !typeName.equals(fileType.getName())) {
Trinity<String, String, Boolean> trinity = myUnresolvedRemovedMappings.get(matcher);
myRemovedMappings.put(matcher, Pair.create(fileType, trinity != null && trinity.third));
}
}
Map<FileNameMatcher, Pair<FileType, Boolean>> getRemovedMappings() {
return myRemovedMappings;
}
@@ -38,14 +38,16 @@
<actions>
<group id="RemoteServersViewToolbar">
<action id="RemoteServers.RunServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.RunServerAction"/>
<action id="RemoteServers.DebugServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DebugServerAction"/>
<action id="RemoteServers.StopServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.StopServerAction"/>
<action id="RemoteServers.EditServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.EditConfigurationAction"/>
<separator/>
<action id="RemoteServers.DeployAll" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployAllAction"/>
<action id="RemoteServers.ConnectServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.RemoteServerConnectAction"/>
<action id="RemoteServers.DisconnectServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.RemoteServerDisconnectAction"/>
<action id="RemoteServers.EditServerConfig" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.RemoteServerConfigAction"/>
<action id="RemoteServers.ChooseServerDeployment" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.ChooseDeploymentAction"/>
<action id="RemoteServers.ChooseServerDeploymentWithDebug" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.ChooseDeploymentWithDebugAction"/>
<action id="Servers.Deploy" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployAction"/>
<action id="Servers.Undeploy" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.UndeployAction"/>
<action id="Servers.DeployWithDebug" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployWithDebugAction"/>
<action id="RemoteServers.EditDeploymentConfig" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeploymentConfigAction"/>
</group>
</actions>
</idea-plugin>
@@ -6,18 +6,16 @@ import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.NodeRenderer;
import com.intellij.ide.util.treeView.TreeVisitor;
import com.intellij.openapi.application.ModalityState;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.remoteServer.impl.runtime.ui.tree.TreeBuilderBase;
import com.intellij.remoteServer.runtime.ConnectionStatus;
import com.intellij.remoteServer.runtime.ServerConnection;
@@ -108,13 +106,10 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
new DoubleClickListener() {
@Override
protected boolean onDoubleClick(MouseEvent event) {
Set<ServersTreeStructure.RemoteServerNode> nodes = getSelectedRemoteServerNodes();
if (nodes.size() == 1) {
RemoteServer<?> server = nodes.iterator().next().getValue();
ServerConnectionManager.getInstance().getOrCreateConnection(server);
return true;
}
return false;
AnAction connectAction = ActionManager.getInstance().getAction("RemoteServers.ConnectServer");
AnActionEvent actionEvent = AnActionEvent.createFromInputEvent(connectAction, event, ActionPlaces.UNKNOWN);
connectAction.actionPerformed(actionEvent);
return true;
}
}.installOn(myTree);
}
@@ -265,18 +260,6 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
return this;
}
public Set<ServerNode> getSelectedServerNodes() {
return myBuilder.getSelectedElements(ServerNode.class);
}
public Set<DeploymentNode> getSelectedDeploymentNodes() {
return myBuilder.getSelectedElements(DeploymentNode.class);
}
public Set<ServersTreeStructure.RemoteServerNode> getSelectedRemoteServerNodes() {
return myBuilder.getSelectedElements(ServersTreeStructure.RemoteServerNode.class);
}
@Override
public void dispose() {
}
@@ -5,18 +5,24 @@ import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public interface DeploymentNode {
public interface DeploymentNode extends ServersTreeNode {
@NotNull
ServerNode getServerNode();
boolean isRedeployActionEnabled();
void redeploy();
boolean isDeployActionVisible();
boolean isDeployActionEnabled();
void deploy();
boolean isUndeployActionEnabled();
void undeploy();
boolean isEditConfigurationActionEnabled();
void editConfiguration();
boolean isDebugActionVisible();
void deployWithDebug();
boolean isDeployed();
@@ -1,26 +1,9 @@
package com.intellij.remoteServer.impl.runtime.ui.tree;
import com.intellij.execution.Executor;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public interface ServerNode {
boolean isConnected();
boolean isStopActionEnabled();
void stopServer();
public interface ServerNode extends ServersTreeNode {
boolean isStartActionEnabled(@NotNull Executor executor);
void startServer(@NotNull Executor executor);
boolean isDeployActionEnabled();
void deploy(AnActionEvent e);
boolean isDeployAllActionEnabled();
void deployAll();
void editConfiguration();
}
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree;
public interface ServersTreeNode {
}
@@ -3,6 +3,7 @@ package com.intellij.remoteServer.impl.runtime.ui.tree;
import com.intellij.execution.Executor;
import com.intellij.execution.ProgramRunnerUtil;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.impl.RunDialog;
import com.intellij.execution.runners.ExecutionEnvironment;
@@ -18,13 +19,16 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.RemoteServersManager;
import com.intellij.remoteServer.configuration.ServerConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurationManager;
import com.intellij.remoteServer.impl.configuration.SingleRemoteServerConfigurable;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
import com.intellij.remoteServer.impl.runtime.deployment.DeploymentTaskImpl;
import com.intellij.remoteServer.impl.runtime.log.DeploymentLogManagerImpl;
import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl;
@@ -38,6 +42,7 @@ import com.intellij.remoteServer.runtime.deployment.DeploymentStatus;
import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.ContainerUtil;
import icons.RemoteServersIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -160,50 +165,65 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
return ServerConnectionManager.getInstance().getConnection(getValue());
}
@Override
public boolean isConnected() {
ServerConnection<?> connection = getConnection();
return connection != null && connection.getStatus() == ConnectionStatus.CONNECTED;
}
@Override
public boolean isDeployActionEnabled() {
return true;
public void deploy(AnActionEvent e) {
doDeploy(e, DefaultRunExecutor.getRunExecutorInstance(), "Deploy Configuration", true);
}
@Override
public void deploy(AnActionEvent e) {
final ServerType<? extends ServerConfiguration> serverType = getValue().getType();
public void deployWithDebug(AnActionEvent e) {
doDeploy(e, DefaultDebugExecutor.getDebugExecutorInstance(), "Deploy and Debug Configuration", false);
}
public void doDeploy(AnActionEvent e, final Executor executor, String popupTitle, boolean canCreate) {
final RemoteServer<?> server = getValue();
final ServerType<? extends ServerConfiguration> serverType = server.getType();
final DeploymentConfigurationManager configurationManager = DeploymentConfigurationManager.getInstance(doGetProject());
List<RunnerAndConfigurationSettings> list = new ArrayList<RunnerAndConfigurationSettings>(configurationManager.getDeploymentConfigurations(serverType));
list.add(null);
ListPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<RunnerAndConfigurationSettings>("Deploy Configuration", list) {
@Override
public Icon getIconFor(RunnerAndConfigurationSettings value) {
return value != null ? serverType.getIcon() : null;
}
List<RunnerAndConfigurationSettings> list
= ContainerUtil.filter(configurationManager.getDeploymentConfigurations(serverType),
new Condition<RunnerAndConfigurationSettings>() {
@NotNull
@Override
public String getTextFor(RunnerAndConfigurationSettings value) {
return value != null ? value.getName() : "Create...";
}
@Override
public boolean value(RunnerAndConfigurationSettings settings) {
DeployToServerRunConfiguration configuration =
(DeployToServerRunConfiguration)settings.getConfiguration();
return StringUtil.equals(server.getName(), configuration.getServerName());
}
});
if (canCreate) {
list.add(null);
}
ListPopup popup =
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<RunnerAndConfigurationSettings>(popupTitle, list) {
@Override
public Icon getIconFor(RunnerAndConfigurationSettings value) {
return value != null ? serverType.getIcon() : null;
}
@Override
public PopupStep onChosen(final RunnerAndConfigurationSettings selectedValue, boolean finalChoice) {
return doFinalStep(new Runnable() {
@Override
public void run() {
if (selectedValue != null) {
ProgramRunnerUtil.executeConfiguration(doGetProject(), selectedValue, DefaultRunExecutor.getRunExecutorInstance());
@NotNull
@Override
public String getTextFor(RunnerAndConfigurationSettings value) {
return value != null ? value.getName() : "Create...";
}
@Override
public PopupStep onChosen(final RunnerAndConfigurationSettings selectedValue, boolean finalChoice) {
return doFinalStep(new Runnable() {
@Override
public void run() {
if (selectedValue != null) {
ProgramRunnerUtil.executeConfiguration(doGetProject(), selectedValue, executor);
}
else {
configurationManager.createAndRunConfiguration(serverType, RemoteServerNode.this.getValue());
}
}
else {
configurationManager.createAndRunConfiguration(serverType, RemoteServerNode.this.getValue());
}
}
});
}
});
});
}
});
if (e.getInputEvent() instanceof MouseEvent) {
popup.show(new RelativePoint((MouseEvent)e.getInputEvent()));
}
@@ -212,45 +232,10 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
}
}
@Override
public boolean isStopActionEnabled() {
return isConnected();
}
@Override
public void stopServer() {
ServerConnection<?> connection = getConnection();
if (connection != null) {
connection.disconnect();
}
}
@Override
public void editConfiguration() {
ShowSettingsUtil.getInstance().editConfigurable(doGetProject(), new SingleRemoteServerConfigurable(getValue(), null, false));
}
@Override
public boolean isStartActionEnabled(@NotNull Executor executor) {
ServerConnection connection = getConnection();
return executor.equals(DefaultRunExecutor.getRunExecutorInstance()) &&
(connection == null || connection.getStatus() == ConnectionStatus.DISCONNECTED);
}
@Override
public void startServer(@NotNull Executor executor) {
ServerConnectionManager.getInstance().getOrCreateConnection(getValue());
}
@Override
public boolean isDeployAllActionEnabled() {
return false;
}
@Override
public void deployAll() {
}
@Nullable
private Icon getStatusIcon(final ConnectionStatus status) {
switch (status) {
@@ -278,23 +263,42 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
}
@Override
public boolean isRedeployActionEnabled() {
public boolean isDeployActionVisible() {
DeploymentTask<?> deploymentTask = getValue().getDeploymentTask();
return deploymentTask instanceof DeploymentTaskImpl<?> && ((DeploymentTaskImpl)deploymentTask).getExecutionEnvironment().getRunnerAndConfigurationSettings() != null;
}
@Override
public void redeploy() {
public boolean isDeployActionEnabled() {
return true;
}
@Override
public void deploy() {
doDeploy(DefaultRunExecutor.getRunExecutorInstance());
}
public void doDeploy(Executor executor) {
DeploymentTask<?> deploymentTask = getValue().getDeploymentTask();
if (deploymentTask != null) {
ExecutionEnvironment environment = ((DeploymentTaskImpl)deploymentTask).getExecutionEnvironment();
RunnerAndConfigurationSettings settings = environment.getRunnerAndConfigurationSettings();
if (settings != null) {
ProgramRunnerUtil.executeConfiguration(doGetProject(), settings, DefaultRunExecutor.getRunExecutorInstance());
ProgramRunnerUtil.executeConfiguration(doGetProject(), settings, executor);
}
}
}
@Override
public boolean isDebugActionVisible() {
return myParentNode.getValue().getType().createDebugConnector() != null;
}
@Override
public void deployWithDebug() {
doDeploy(DefaultDebugExecutor.getDebugExecutorInstance());
}
@Override
public boolean isUndeployActionEnabled() {
DeploymentRuntime runtime = getValue().getRuntime();
@@ -309,12 +313,10 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
}
}
@Override
public boolean isEditConfigurationActionEnabled() {
public boolean isEditConfigurationActionVisible() {
return getValue().getDeploymentTask() != null;
}
@Override
public void editConfiguration() {
DeploymentTask<?> task = getValue().getDeploymentTask();
if (task != null) {
@@ -396,7 +398,7 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
}
}
public class DeploymentLogNode extends AbstractTreeNode<Pair<LoggingHandlerImpl, String>> implements LogProvidingNode {
public class DeploymentLogNode extends AbstractTreeNode<Pair<LoggingHandlerImpl, String>> implements ServersTreeNode, LogProvidingNode {
@NotNull private final DeploymentNodeImpl myDeploymentNode;
public DeploymentLogNode(@NotNull Pair<LoggingHandlerImpl, String> value, @NotNull DeploymentNodeImpl deploymentNode) {
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import org.jetbrains.annotations.NotNull;
public class ChooseDeploymentAction extends ServersTreeAction<ServersTreeStructure.RemoteServerNode> {
public ChooseDeploymentAction() {
super("Deploy", "Deploy a chosen item to the selected remote server", AllIcons.Nodes.Deploy);
}
@Override
protected Class<ServersTreeStructure.RemoteServerNode> getTargetNodeClass() {
return ServersTreeStructure.RemoteServerNode.class;
}
@Override
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e, ServersTreeStructure.RemoteServerNode node) {
node.deploy(e);
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import org.jetbrains.annotations.NotNull;
public class ChooseDeploymentWithDebugAction extends ServersTreeAction<ServersTreeStructure.RemoteServerNode> {
public ChooseDeploymentWithDebugAction() {
super("Debug", "Deploy and debug a chosen item on the selected remote server", AllIcons.Actions.StartDebugger);
}
@Override
protected Class<ServersTreeStructure.RemoteServerNode> getTargetNodeClass() {
return ServersTreeStructure.RemoteServerNode.class;
}
@Override
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e, ServersTreeStructure.RemoteServerNode node) {
node.deployWithDebug(e);
}
}
@@ -1,19 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.execution.Executor;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.icons.AllIcons;
/**
* @author michael.golubev
*/
public class DebugServerAction extends RunServerActionBase {
public DebugServerAction() {
super("Debug", "Start the selected server in debug mode", AllIcons.Actions.StartDebugger);
}
@Override
protected Executor getExecutor() {
return DefaultDebugExecutor.getDebugExecutorInstance();
}
}
@@ -1,67 +1,50 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* @author michael.golubev
*/
public class DeployAction extends ServersTreeActionBase {
public class DeployAction extends ServersTreeAction<DeploymentNode> {
public DeployAction() {
super("Deploy", "Deploy the selected item", AllIcons.Nodes.Deploy);
}
@Override
protected void updatePresentation(@NotNull Presentation presentation, @Nullable ServersToolWindowContent content) {
if (content != null) {
Set<DeploymentNode> nodes = content.getSelectedDeploymentNodes();
if (nodes.size() == 1) {
DeploymentNode node = nodes.iterator().next();
if (node.isDeployed()) {
presentation.setText("Redeploy");
presentation.setDescription("Redeploy '" + node.getDeploymentName() + "'");
return;
}
}
}
presentation.setText(getTemplatePresentation().getText());
presentation.setDescription(getTemplatePresentation().getDescription());
protected Class<DeploymentNode> getTargetNodeClass() {
return DeploymentNode.class;
}
@Override
protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) {
Set<DeploymentNode> deploymentNodes = content.getSelectedDeploymentNodes();
Set<ServerNode> serverNodes = content.getSelectedServerNodes();
if (deploymentNodes.size() + serverNodes.size() != 1) return false;
for (DeploymentNode node : deploymentNodes) {
if (!node.isRedeployActionEnabled()) {
return false;
}
protected void updatePresentation(@NotNull Presentation presentation, @Nullable DeploymentNode node) {
if (node != null && node.isDeployed()) {
presentation.setText("Redeploy");
presentation.setDescription("Redeploy '" + node.getDeploymentName() + "'");
}
for (ServerNode serverNode : serverNodes) {
if (!serverNode.isDeployActionEnabled()) {
return false;
}
else {
presentation.setText(getTemplatePresentation().getText());
presentation.setDescription(getTemplatePresentation().getDescription());
}
return true;
}
@Override
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) {
for (DeploymentNode node : content.getSelectedDeploymentNodes()) {
node.redeploy();
}
for (ServerNode node : content.getSelectedServerNodes()) {
node.deploy(e);
}
protected boolean isVisible4(DeploymentNode node) {
return node.isDeployActionVisible();
}
@Override
protected boolean isEnabled4(DeploymentNode node) {
return node.isDeployActionEnabled();
}
@Override
protected void doActionPerformed(DeploymentNode node) {
node.deploy();
}
}
@@ -1,27 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
/**
* @author michael.golubev
*/
public class DeployAllAction extends ServerActionBase {
public DeployAllAction() {
super("Deploy All", "Deploy all the artifacts of the selected server", AllIcons.Nodes.Deploy);
}
@Override
protected void performAction(@NotNull ServerNode serverNode) {
if (serverNode.isDeployAllActionEnabled()) {
serverNode.deployAll();
}
}
@Override
protected boolean isEnabledForServer(@NotNull ServerNode serverNode) {
return serverNode.isDeployAllActionEnabled();
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
public class DeployWithDebugAction extends ServersTreeAction<DeploymentNode> {
public DeployWithDebugAction() {
super("Debug", "Deploy and debug the selected item", AllIcons.Actions.StartDebugger);
}
@Override
protected Class<DeploymentNode> getTargetNodeClass() {
return DeploymentNode.class;
}
@Override
protected boolean isVisible4(DeploymentNode node) {
return node.isDeployActionVisible() && node.isDebugActionVisible();
}
@Override
protected boolean isEnabled4(DeploymentNode node) {
return node.isDeployActionEnabled();
}
@Override
protected void doActionPerformed(DeploymentNode node) {
node.deployWithDebug();
}
}
@@ -1,52 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author nik
*/
public abstract class DeploymentActionBase extends ServersTreeActionBase {
protected DeploymentActionBase(String text, String description, Icon icon) {
super(text, description, icon);
}
protected abstract void perform(@NotNull List<DeploymentNode> nodes, ServersToolWindowContent content, AnActionEvent e);
protected abstract boolean isApplicable(@NotNull DeploymentNode node);
@Override
public void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) {
List<DeploymentNode> toPerform = new ArrayList<DeploymentNode>();
for (DeploymentNode node : content.getSelectedDeploymentNodes()) {
if (isApplicable(node)) {
toPerform.add(node);
}
}
if (!toPerform.isEmpty()) {
perform(toPerform, content, e);
}
}
@Override
protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) {
Set<?> selectedElements = content.getBuilder().getSelectedElements();
if (selectedElements.isEmpty() || selectedElements.size() != content.getSelectedDeploymentNodes().size()) {
return false;
}
for (DeploymentNode node : content.getSelectedDeploymentNodes()) {
if (!isApplicable(node)) {
return false;
}
}
return true;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
public class DeploymentConfigAction extends EditConfigurationActionBase<ServersTreeStructure.DeploymentNodeImpl> {
public DeploymentConfigAction() {
super("Edit the selected deployment run configuration");
}
@Override
protected Class<ServersTreeStructure.DeploymentNodeImpl> getTargetNodeClass() {
return ServersTreeStructure.DeploymentNodeImpl.class;
}
@Override
protected boolean isVisible4(ServersTreeStructure.DeploymentNodeImpl node) {
return node.isEditConfigurationActionVisible();
}
@Override
protected void doActionPerformed(ServersTreeStructure.DeploymentNodeImpl node) {
node.editConfiguration();
}
}
@@ -1,42 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* @author michael.golubev
*/
public class EditConfigurationAction extends ServersTreeActionBase {
public EditConfigurationAction() {
super("Edit Configuration", "Edit configuration of the selected server", AllIcons.Actions.EditSource);
}
@Override
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) {
Set<DeploymentNode> deploymentNodes = content.getSelectedDeploymentNodes();
Set<ServerNode> serverNodes = content.getSelectedServerNodes();
if (deploymentNodes.size() == 1) {
deploymentNodes.iterator().next().editConfiguration();
}
else {
serverNodes.iterator().next().editConfiguration();
}
}
@Override
protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) {
Set<DeploymentNode> deploymentNodes = content.getSelectedDeploymentNodes();
Set<ServerNode> serverNodes = content.getSelectedServerNodes();
if (deploymentNodes.size() + serverNodes.size() != 1) return false;
if (deploymentNodes.size() == 1) {
return deploymentNodes.iterator().next().isEditConfigurationActionEnabled();
}
return true;
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNode;
public abstract class EditConfigurationActionBase<T extends ServersTreeNode> extends ServersTreeAction<T> {
public EditConfigurationActionBase(String description) {
super("Edit Configuration", description, AllIcons.Actions.EditSource);
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
public class RemoteServerConfigAction extends EditConfigurationActionBase<ServersTreeStructure.RemoteServerNode> {
public RemoteServerConfigAction() {
super("Edit the selected remote server configuration");
}
@Override
protected Class<ServersTreeStructure.RemoteServerNode> getTargetNodeClass() {
return ServersTreeStructure.RemoteServerNode.class;
}
@Override
protected void doActionPerformed(ServersTreeStructure.RemoteServerNode node) {
node.editConfiguration();
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.remoteServer.runtime.ServerConnectionManager;
public class RemoteServerConnectAction extends ServersTreeAction<ServersTreeStructure.RemoteServerNode> {
public RemoteServerConnectAction() {
super("Connect", "Connect to the selected remote server", AllIcons.Actions.Execute);
}
@Override
protected Class<ServersTreeStructure.RemoteServerNode> getTargetNodeClass() {
return ServersTreeStructure.RemoteServerNode.class;
}
@Override
protected boolean isEnabled4(ServersTreeStructure.RemoteServerNode node) {
return !node.isConnected();
}
@Override
protected void doActionPerformed(ServersTreeStructure.RemoteServerNode node) {
ServerConnectionManager.getInstance().getOrCreateConnection(node.getValue());
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnectionManager;
public class RemoteServerDisconnectAction extends ServersTreeAction<ServersTreeStructure.RemoteServerNode> {
public RemoteServerDisconnectAction() {
super("Disconnect", "Disconnect from the selected remote server", AllIcons.Actions.Suspend);
}
@Override
protected Class<ServersTreeStructure.RemoteServerNode> getTargetNodeClass() {
return ServersTreeStructure.RemoteServerNode.class;
}
@Override
protected boolean isEnabled4(ServersTreeStructure.RemoteServerNode node) {
return node.isConnected();
}
@Override
protected void doActionPerformed(ServersTreeStructure.RemoteServerNode node) {
ServerConnection<?> connection = ServerConnectionManager.getInstance().getConnection(node.getValue());
if (connection != null) {
connection.disconnect();
}
}
}
@@ -1,20 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.execution.Executor;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.icons.AllIcons;
/**
* @author michael.golubev
*/
public class RunServerAction extends RunServerActionBase {
public RunServerAction() {
super("Run/Connect", "Run/Connect to the selected server", AllIcons.Actions.Execute);
}
@Override
protected Executor getExecutor() {
return DefaultRunExecutor.getRunExecutorInstance();
}
}
@@ -1,31 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.execution.Executor;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author michael.golubev
*/
public abstract class RunServerActionBase extends ServerActionBase {
protected RunServerActionBase(String text, String description, Icon icon) {
super(text, description, icon);
}
protected void performAction(@NotNull ServerNode serverNode) {
if (serverNode.isStartActionEnabled(getExecutor())) {
serverNode.startServer(getExecutor());
}
}
@Override
protected boolean isEnabledForServer(@NotNull ServerNode serverNode) {
return serverNode.isStartActionEnabled(getExecutor());
}
protected abstract Executor getExecutor();
}
@@ -1,46 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Set;
/**
* @author michael.golubev
*/
public abstract class ServerActionBase extends ServersTreeActionBase {
protected ServerActionBase(String text, String description, Icon icon) {
super(text, description, icon);
}
@Override
protected final boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) {
Set<ServerNode> selectedServerNodes = content.getSelectedServerNodes();
Set<?> selectedElements = content.getBuilder().getSelectedElements();
if (selectedElements.size() != selectedServerNodes.size() || selectedElements.isEmpty()) {
return false;
}
for (ServerNode selectedServer : selectedServerNodes) {
if (!isEnabledForServer(selectedServer)) {
return false;
}
}
return true;
}
@Override
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) {
for (ServerNode node : content.getSelectedServerNodes()) {
performAction(node);
}
}
protected abstract void performAction(@NotNull ServerNode serverNode);
protected abstract boolean isEnabledForServer(@NotNull ServerNode serverNode);
}
@@ -0,0 +1,91 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Set;
public abstract class ServersTreeAction<T extends ServersTreeNode> extends AnAction {
protected ServersTreeAction(String text, String description, Icon icon) {
super(text, description, icon);
}
@Override
public void update(@NotNull AnActionEvent e) {
Presentation presentation = e.getPresentation();
T targetNode = getTargetNode(e);
boolean visible = false;
boolean enabled = false;
if (targetNode != null) {
visible = isVisible4(targetNode);
if (visible) {
enabled = isEnabled4(targetNode);
}
}
presentation.setVisible(visible);
presentation.setEnabled(enabled);
updatePresentation(presentation, targetNode);
}
private T getTargetNode(AnActionEvent e) {
ServersToolWindowContent content = getContent(e);
if (content == null) {
return null;
}
Set<Object> selectedElements = content.getBuilder().getSelectedElements();
if (selectedElements.size() != 1) {
return null;
}
ServersTreeNode node = (ServersTreeNode)selectedElements.iterator().next();
Class<T> targetNodeClass = getTargetNodeClass();
if (!targetNodeClass.isInstance(node)) {
return null;
}
return targetNodeClass.cast(node);
}
private static ServersToolWindowContent getContent(AnActionEvent e) {
return e.getData(ServersToolWindowContent.KEY);
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
T targetNode = getTargetNode(e);
if (targetNode != null && isVisible4(targetNode) && isEnabled4(targetNode)) {
doActionPerformed(getContent(e), e, targetNode);
}
}
protected boolean isVisible4(T node) {
return true;
}
protected boolean isEnabled4(T node) {
return true;
}
protected void updatePresentation(@NotNull Presentation presentation, @Nullable T node) {
}
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e, T node) {
doActionPerformed(node);
}
protected void doActionPerformed(T node) {
throw new UnsupportedOperationException();
}
protected abstract Class<T> getTargetNodeClass();
}
@@ -1,44 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author michael.golubev
*/
public abstract class ServersTreeActionBase extends AnAction {
protected ServersTreeActionBase(String text, String description, Icon icon) {
super(text, description, icon);
}
@Override
public void update(AnActionEvent e) {
ServersToolWindowContent content = e.getData(ServersToolWindowContent.KEY);
Presentation presentation = e.getPresentation();
presentation.setEnabled(content != null && isEnabled(content, e));
updatePresentation(presentation, content);
}
protected void updatePresentation(@NotNull Presentation presentation, @Nullable ServersToolWindowContent content) {
}
@Override
public void actionPerformed(AnActionEvent e) {
ServersToolWindowContent content = e.getData(ServersToolWindowContent.KEY);
if (content == null) {
return;
}
doActionPerformed(content, e);
}
protected abstract boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e);
protected abstract void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e);
}
@@ -1,49 +0,0 @@
/*
* Copyright 2000-2013 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.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Set;
/**
* @author michael.golubev
*/
public abstract class SingleServerActionBase extends ServersTreeActionBase {
protected SingleServerActionBase(String text, String description, Icon icon) {
super(text, description, icon);
}
@Override
protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) {
doActionPerformed(content, content.getSelectedServerNodes().iterator().next());
}
@Override
protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) {
Set<ServerNode> serverNodes = content.getSelectedServerNodes();
return content.getBuilder().getSelectedElements().size() == serverNodes.size() && serverNodes.size() == 1 &&
isEnabledForServer(serverNodes.iterator().next());
}
protected abstract boolean isEnabledForServer(ServerNode serverNode);
protected abstract void doActionPerformed(@NotNull ServersToolWindowContent content, @NotNull ServerNode server);
}
@@ -1,26 +0,0 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode;
import org.jetbrains.annotations.NotNull;
/**
* @author michael.golubev
*/
public class StopServerAction extends ServerActionBase {
public StopServerAction() {
super("Stop/Disconnect", "Stop/disconnect from the selected server", AllIcons.Actions.Suspend);
}
protected void performAction(@NotNull ServerNode serverNode) {
if (serverNode.isStopActionEnabled()) {
serverNode.stopServer();
}
}
@Override
protected boolean isEnabledForServer(@NotNull ServerNode serverNode) {
return serverNode.isStopActionEnabled();
}
}
@@ -1,30 +1,29 @@
package com.intellij.remoteServer.impl.runtime.ui.tree.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author michael.golubev
*/
public class UndeployAction extends DeploymentActionBase {
public class UndeployAction extends ServersTreeAction<DeploymentNode> {
public UndeployAction() {
super("Undeploy", "Undeploy the selected item", AllIcons.Nodes.Undeploy);
}
@Override
protected boolean isApplicable(@NotNull DeploymentNode node) {
protected Class<DeploymentNode> getTargetNodeClass() {
return DeploymentNode.class;
}
@Override
protected boolean isEnabled4(DeploymentNode node) {
return node.isUndeployActionEnabled();
}
@Override
protected void perform(@NotNull List<DeploymentNode> nodes, ServersToolWindowContent content, AnActionEvent e) {
for (DeploymentNode node : nodes) {
node.undeploy();
}
protected void doActionPerformed(DeploymentNode node) {
node.undeploy();
}
}
@@ -38,7 +38,7 @@ public class DateFormatUtilTest {
@Test
public void testBasics() throws ParseException {
Clock.setTime(2004, 11, 10, 17, 10);
Clock.setTime(2004, Calendar.DECEMBER, 10, 17, 10);
doTestPrettyDate("Today", "10.12.2004 17.00.00");
doTestPrettyDate("Today", "10.12.2004 00.00.00");
@@ -49,7 +49,7 @@ public class DateFormatUtilTest {
@Test
public void testTime() throws Exception {
Clock.setTime(2004, 11, 10, 17, 10, 15);
Clock.setTime(1980, Calendar.DECEMBER, 10, 17, 10, 15);
if (SystemInfo.isMac) {
assertEquals("17:10", DateFormatUtil.formatTime(Clock.getTime()));
@@ -60,7 +60,7 @@ public class DateFormatUtilTest {
assertEquals("17:10:15", printTimeForLocale("de_DE.UTF-8", Clock.getTime()));
}
else if (SystemInfo.isWinVistaOrNewer) {
long time = new Date().getTime();
long time = Clock.getTime();
assertEquals(printWindowsTime(time), DateFormatUtil.formatTimeWithSeconds(time));
}
else {
@@ -73,7 +73,7 @@ public class DateFormatUtilTest {
@Test
public void testPrettyDateTime() throws ParseException {
Clock.setTime(2004, 11, 10, 17, 0);
Clock.setTime(2004, Calendar.DECEMBER, 10, 17, 0);
doTestDateTime("Moments ago", "10.12.2004 16.59.31");
doTestDateTime("A minute ago", "10.12.2004 16.59.29");
doTestDateTime("5 minutes ago", "10.12.2004 16.55.00");
@@ -82,7 +82,7 @@ public class DateFormatUtilTest {
doTestDateTime("Yesterday " + DateFormatUtil.formatTime(DATE_FORMAT.parse("09.12.2004 15.00.00")), "09.12.2004 15.00.00");
doTestDateTime("Today " + DateFormatUtil.formatTime(DATE_FORMAT.parse("10.12.2004 19.00.00")), "10.12.2004 19.00.00");
Clock.setTime(2004, 0, 1, 15, 53);
Clock.setTime(2004, Calendar.JANUARY, 1, 15, 53);
doTestDateTime(DateFormatUtil.formatDateTime(DATE_FORMAT.parse("01.01.2003 15.53.00")), "01.01.2003 15.53.00");
doTestDateTime("Yesterday " + DateFormatUtil.formatTime(DATE_FORMAT.parse("31.12.2003 15.00.00")), "31.12.2003 15.00.00");
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -243,12 +244,9 @@ public class UnnecessaryUnboxingInspection extends BaseInspection {
if (!(expression instanceof PsiMethodCallExpression)) {
return false;
}
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)expression;
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final PsiExpression qualifier =
methodExpression.getQualifierExpression();
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
return false;
}
@@ -261,31 +259,45 @@ public class UnnecessaryUnboxingInspection extends BaseInspection {
return false;
}
final String methodName = methodExpression.getReferenceName();
final String unboxingMethod =
s_unboxingMethods.get(qualifierTypeName);
final String unboxingMethod = s_unboxingMethods.get(qualifierTypeName);
return unboxingMethod.equals(methodName);
}
private boolean isSameMethodCalledWithoutUnboxing(
@NotNull PsiCallExpression callExpression,
@NotNull PsiMethodCallExpression unboxingExpression) {
final PsiExpressionList argumentList =
callExpression.getArgumentList();
private boolean isSameMethodCalledWithoutUnboxing(@NotNull PsiCallExpression callExpression,
@NotNull PsiMethodCallExpression unboxingExpression) {
final PsiExpressionList argumentList = callExpression.getArgumentList();
if (argumentList == null) {
return false;
}
final PsiExpression[] expressions = argumentList.getExpressions();
final PsiMethod originalMethod =
callExpression.resolveMethod();
final PsiMethod originalMethod = callExpression.resolveMethod();
if (originalMethod == null) {
return false;
}
final String name = originalMethod.getName();
final PsiClass containingClass =
originalMethod.getContainingClass();
final PsiExpression qualifierExpression;
if (callExpression instanceof PsiMethodCallExpression) {
qualifierExpression = ((PsiMethodCallExpression)callExpression).getMethodExpression().getQualifierExpression();
} else if (callExpression instanceof PsiNewExpression) {
qualifierExpression = ((PsiNewExpression)callExpression).getQualifier();
} else {
return false;
}
final PsiClass containingClass;
if (qualifierExpression == null) {
final PsiElement scope = callExpression.resolveMethodGenerics().getCurrentFileResolveScope();
containingClass = scope instanceof PsiClass ? (PsiClass)scope : null;
}
else {
containingClass = PsiUtil.resolveClassInType(GenericsUtil.getVariableTypeByExpressionType(qualifierExpression.getType()));
}
if (containingClass == null) {
return false;
}
final PsiType[] types = PsiType.createArray(expressions.length);
for (int i = 0; i < expressions.length; i++) {
final PsiExpression expression = expressions[i];
@@ -294,20 +306,17 @@ public class UnnecessaryUnboxingInspection extends BaseInspection {
if (!(type instanceof PsiPrimitiveType)) {
return false;
}
final PsiPrimitiveType primitiveType =
(PsiPrimitiveType)type;
final PsiPrimitiveType primitiveType = (PsiPrimitiveType)type;
types[i] = primitiveType.getBoxedType(unboxingExpression);
}
else {
types[i] = type;
}
}
final PsiMethod[] methods =
containingClass.findMethodsByName(name, true);
final PsiMethod[] methods = containingClass.findMethodsByName(name, true);
for (final PsiMethod method : methods) {
if (!originalMethod.equals(method)) {
if (MethodCallUtils.isApplicable(method,
PsiSubstitutor.EMPTY, types)) {
if (MethodCallUtils.isApplicable(method, PsiSubstitutor.EMPTY, types)) {
return false;
}
}
@@ -38,4 +38,19 @@ public class UnnecessaryUnboxing {
Integer boxcutter(Integer i) {
return i.intValue();
}
}
class B23 {
public void set(double value) {}
}
class A23 extends B23 {
public void set(Object value) {}
private A23() {
Object o = 2d;
set(((Double) o).doubleValue());
B23 b23 = new B23();
b23.set(((Double) o).doubleValue());
}
}
@@ -43,4 +43,17 @@ public class UnnecessaryUnboxing {
byte cast(Integer v) {
return (byte)v.intValue();
}
}
class B23 {
public void set(double value) {}
}
class A23 extends B23 {
public void set(Object value) {}
private A23() {
Object o = 2d;
B23 b23 = new B23();
b23.set(((Double) o).doubleValue());
}
}
@@ -55,5 +55,10 @@
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary unboxing</problem_class>
<description>Unnecessary unboxing &lt;code&gt;b.byteValue()&lt;/code&gt; #loc</description>
</problem>
<problem>
<file>UnnecessaryUnboxing.java</file>
<line>57</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary unboxing</problem_class>
<description>Unnecessary unboxing &lt;code&gt;((Double) o).doubleValue()&lt;/code&gt; #loc</description>
</problem>
</problems>
@@ -26,7 +26,6 @@ import com.intellij.tasks.TaskBundle;
import com.intellij.tasks.TaskRepositoryType;
import com.intellij.tasks.impl.BaseRepository;
import com.intellij.tasks.impl.BaseRepositoryImpl;
import com.intellij.tasks.impl.TaskUtil;
import com.intellij.tasks.impl.httpclient.ResponseUtil;
import com.intellij.tasks.trello.model.TrelloBoard;
import com.intellij.tasks.trello.model.TrelloCard;
@@ -320,8 +319,6 @@ public final class TrelloRepository extends BaseRepositoryImpl {
HttpClient client = getHttpClient();
client.executeMethod(method);
String entityContent = ResponseUtil.getResponseContentAsString(method);
TaskUtil.prettyFormatJsonToLog(LOG, entityContent);
// LOG.debug("Response size: " + method.getResponseHeader("Content-Length").getValue() + " bytes");
if (method.getStatusCode() != HttpStatus.SC_OK) {
Header header = method.getResponseHeader("Content-Type");
if (header != null && header.getValue().startsWith("text/plain")) {
@@ -43,7 +43,7 @@ import java.util.List;
* @author Mikhail Golubev
*/
public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepository> {
private static final Logger LOG = Logger.getInstance("#com.intellij.tasks.trello.TrelloRepositoryEditor");
private static final Logger LOG = Logger.getInstance(TrelloRepositoryEditor.class);
private static final TrelloBoard UNSPECIFIED_BOARD = new TrelloBoard() {
@NotNull
@@ -83,9 +83,10 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepositor
@Override
protected void textChanged(DocumentEvent e) {
String password = String.valueOf(myPasswordText.getPassword());
if (password.equals(myRepository.getPassword())) {
if (password.isEmpty() || password.equals(myRepository.getPassword())) {
return;
}
LOG.debug("Authentication token was changed");
myRepository.setPassword(password);
new BoardsDownloader(UNSPECIFIED_BOARD) {
@Override
@@ -119,7 +120,6 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepositor
}
});
myBoardComboBox.setRenderer(new TrelloBoardRenderer("Set token first"));
myListComboBox.setRenderer(new TrelloListRenderer("Select board first"));
myListComboBox.addItemListener(new ItemListener() {
@Override
@@ -132,12 +132,14 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepositor
}
}
});
myListComboBox.setRenderer(new TrelloListRenderer("Select board first"));
// Initial setup:
if (myRepository.getCurrentUser() != null) {
new BoardsDownloader(myRepository.getCurrentBoard()) {
@Override
protected List<TrelloBoard> download() throws Exception {
LOG.debug("Updating information about boards available to user when repository setting are shown");
List<TrelloBoard> boards = super.download();
if (myBoard == null) {
return boards;
@@ -157,6 +159,7 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepositor
new ListsDownloader(myRepository.getCurrentList()) {
@Override
protected List<TrelloList> download() throws Exception {
LOG.debug("Updating information about lists of board " + myRepository.getCurrentBoard() + " when repository setting are shown");
List<TrelloList> lists = super.download();
if (myList == null) {
return lists;
@@ -266,6 +269,7 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepositor
return myRepository.fetchUserBoards();
}
@SuppressWarnings("unchecked")
@Override
protected void updateUI(List<TrelloBoard> boards) {
myBoardComboBox.setModel(new DefaultComboBoxModel(boards.toArray()));
@@ -296,6 +300,7 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor<TrelloRepositor
return myRepository.fetchBoardLists();
}
@SuppressWarnings("unchecked")
@Override
protected void updateUI(List<TrelloList> lists) {
myListComboBox.setModel(new DefaultComboBoxModel(lists.toArray()));
@@ -1,6 +1,7 @@
package org.jetbrains.plugins.coursecreator.actions;
import com.intellij.ide.IdeView;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.util.DirectoryChooserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -20,7 +21,7 @@ import javax.swing.*;
public class CCChangeCourseInfo extends DumbAwareAction {
public CCChangeCourseInfo() {
super("Change course information", "Change course information", null);
super("Change Course information", "Change Course Information", null);
}
@Override
@@ -85,6 +86,7 @@ public class CCChangeCourseInfo extends DumbAwareAction {
course.setAuthor(panel.getAuthor());
course.setName(panel.getName());
course.setDescription(panel.getDescription());
ProjectView.getInstance(project).refresh();
}
}
@@ -93,6 +95,7 @@ public class CCChangeCourseInfo extends DumbAwareAction {
CCNewProjectPanel myNewProjectPanel;
public ChangeCourseInfoDialog(@Nullable Project project, CCNewProjectPanel panel) {
super(project);
setTitle("Change Course Information");
myNewProjectPanel = panel;
init();
}
@@ -84,6 +84,7 @@ public class CCRunTestsAction extends AnAction {
if (lessonDir == null) return;
if (course == null) return;
final Lesson lesson = course.getLesson(lessonDir.getName());
if (lesson == null) return;
final Task task = lesson.getTask(taskDir.getName());
if (task == null) {
presentation.setVisible(false);
@@ -54,23 +54,28 @@ public class PyExecuteFileLineMarkerProvider implements LineMarkerProvider {
return new LineMarkerGutterIconRenderer<PsiElement>(this){
@Override
public AnAction getClickAction() {
final DefaultActionGroup group = new DefaultActionGroup();
group.add(new PyRunCurrentFileAction());
final PyExecuteFileExtensionPoint[] extensions =
ApplicationManager.getApplication().getExtensions(PyExecuteFileExtensionPoint.EP_NAME);
for (PyExecuteFileExtensionPoint extension : extensions) {
final AnAction action = extension.getRunAction();
group.add(action);
}
if (group.getChildrenCount() == 1) {
return new PyRunCurrentFileAction();
}
return new AnAction() {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
final ListPopup popup =
new PopupFactoryImpl().createActionGroupPopup(null, group, e.getDataContext(), false, false, false, null, 5);
popup.showInBestPositionFor(e.getDataContext());
final DefaultActionGroup group = new DefaultActionGroup();
group.add(new PyRunCurrentFileAction());
final PyExecuteFileExtensionPoint[] extensions =
ApplicationManager.getApplication().getExtensions(PyExecuteFileExtensionPoint.EP_NAME);
for (PyExecuteFileExtensionPoint extension : extensions) {
final AnAction action = extension.getRunAction();
action.update(e);
if (e.getPresentation().isEnabled())
group.add(action);
}
if (group.getChildrenCount() == 1) {
new PyRunCurrentFileAction().actionPerformed(e);
}
else {
final ListPopup popup =
new PopupFactoryImpl().createActionGroupPopup(null, group, e.getDataContext(), false, false, false, null, 5);
popup.showInBestPositionFor(e.getDataContext());
}
}
};
}
@@ -16,7 +16,10 @@
package com.intellij.psi.impl.source.xml;
import com.intellij.ide.highlighter.DTDFileType;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.search.PsiElementProcessor;
@@ -49,8 +52,6 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef {
super(XmlElementType.XML_ENTITY_REF);
}
private static final Key<String> EVALUATION_IN_PROCESS = Key.create("EvalKey");
@Override
public XmlEntityDecl resolve(PsiFile targetFile) {
String text = getText();
@@ -77,12 +78,12 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef {
if (value == null) {
final PsiManager manager = element.getManager();
if(manager == null){
return resolveEntity(targetElement, entityName, containingFile).getValue();
return doResolveEntity(targetElement, entityName, containingFile).getValue();
}
value = CachedValuesManager.getManager(manager.getProject()).createCachedValue(new CachedValueProvider<XmlEntityDecl>() {
@Override
public Result<XmlEntityDecl> compute() {
return resolveEntity(targetElement, entityName, containingFile);
return doResolveEntity(targetElement, entityName, containingFile);
}
});
@@ -95,95 +96,94 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef {
private static final Key<Boolean> DISABLE_ENTITY_EXPAND = Key.create("disable.entity.expand");
private static CachedValueProvider.Result<XmlEntityDecl> resolveEntity(final PsiElement targetElement, final String entityName, PsiFile contextFile) {
if (targetElement.getUserData(EVALUATION_IN_PROCESS) != null) {
return new CachedValueProvider.Result<XmlEntityDecl>(null,targetElement);
}
try {
targetElement.putUserData(EVALUATION_IN_PROCESS, "");
final List<PsiElement> deps = new ArrayList<PsiElement>();
final XmlEntityDecl[] result = {null};
private static CachedValueProvider.Result<XmlEntityDecl> doResolveEntity(final PsiElement targetElement,
final String entityName,
final PsiFile contextFile) {
return RecursionManager.doPreventingRecursion(targetElement, true, new Computable<CachedValueProvider.Result<XmlEntityDecl>>() {
@Override
public CachedValueProvider.Result<XmlEntityDecl> compute() {
final List<PsiElement> deps = new ArrayList<PsiElement>();
final XmlEntityDecl[] result = {null};
PsiElementProcessor processor = new PsiElementProcessor() {
@Override
public boolean execute(@NotNull PsiElement element) {
if (element instanceof XmlDoctype) {
XmlDoctype xmlDoctype = (XmlDoctype)element;
final String dtdUri = getDtdForEntity(xmlDoctype);
if (dtdUri != null) {
XmlFile file = XmlUtil.getContainingFile(element);
if (file == null) return true;
final XmlFile xmlFile = XmlUtil.findNamespace(file, dtdUri);
if (xmlFile != null) {
if (xmlFile != targetElement) {
deps.add(xmlFile);
if(!XmlUtil.processXmlElements(xmlFile, this,true)) return false;
PsiElementProcessor processor = new PsiElementProcessor() {
@Override
public boolean execute(@NotNull PsiElement element) {
if (element instanceof XmlDoctype) {
XmlDoctype xmlDoctype = (XmlDoctype)element;
final String dtdUri = getDtdForEntity(xmlDoctype);
if (dtdUri != null) {
XmlFile file = XmlUtil.getContainingFile(element);
if (file == null) return true;
final XmlFile xmlFile = XmlUtil.findNamespace(file, dtdUri);
if (xmlFile != null) {
if (xmlFile != targetElement) {
deps.add(xmlFile);
if (!XmlUtil.processXmlElements(xmlFile, this, true)) return false;
}
}
}
final XmlMarkupDecl markupDecl = xmlDoctype.getMarkupDecl();
if (markupDecl != null) {
if (!XmlUtil.processXmlElements(markupDecl, this, true)) return false;
}
}
final XmlMarkupDecl markupDecl = xmlDoctype.getMarkupDecl();
if (markupDecl != null) {
if (!XmlUtil.processXmlElements(markupDecl, this, true)) return false;
else if (element instanceof XmlEntityDecl) {
XmlEntityDecl entityDecl = (XmlEntityDecl)element;
final String declName = entityDecl.getName();
if (StringUtil.equals(declName, entityName)) {
result[0] = entityDecl;
return false;
}
}
return true;
}
else if (element instanceof XmlEntityDecl) {
XmlEntityDecl entityDecl = (XmlEntityDecl)element;
final String declName = entityDecl.getName();
if (declName.equals(entityName)) {
result[0] = entityDecl;
return false;
}
};
FileViewProvider provider = targetElement.getContainingFile().getViewProvider();
deps.add(provider.getPsi(provider.getBaseLanguage()));
boolean notfound = PsiTreeUtil.processElements(targetElement, processor);
if (notfound) {
if (contextFile != targetElement && contextFile != null && contextFile.isValid()) {
notfound = PsiTreeUtil.processElements(contextFile, processor);
}
return true;
}
};
FileViewProvider provider = targetElement.getContainingFile().getViewProvider();
deps.add(provider.getPsi(provider.getBaseLanguage()));
boolean notfound = PsiTreeUtil.processElements(targetElement, processor);
if (notfound) {
if (contextFile != targetElement && contextFile != null && contextFile.isValid()) {
notfound = PsiTreeUtil.processElements(contextFile, processor);
}
}
if (notfound && // no dtd ref at all
targetElement instanceof XmlFile &&
deps.size() == 1 &&
((XmlFile)targetElement).getFileType() != DTDFileType.INSTANCE
) {
XmlDocument document = ((XmlFile)targetElement).getDocument();
final XmlTag rootTag = document != null ? document.getRootTag() : null;
XmlFile descriptorFile = null;
if (notfound && // no dtd ref at all
targetElement instanceof XmlFile &&
deps.size() == 1 &&
((XmlFile)targetElement).getFileType() != DTDFileType.INSTANCE
) {
XmlDocument document = ((XmlFile)targetElement).getDocument();
final XmlTag rootTag = document.getRootTag();
XmlFile descriptorFile = null;
if (HtmlUtil.isHtml5Document(document)) {
descriptorFile = XmlUtil.findXmlFile((XmlFile)targetElement, Html5SchemaProvider.getCharsDtdLocation());
} else if (rootTag != null && document.getUserData(DISABLE_ENTITY_EXPAND) == null) {
final XmlElementDescriptor descriptor = rootTag.getDescriptor();
if (HtmlUtil.isHtml5Document(document)) {
descriptorFile = XmlUtil.findXmlFile((XmlFile)targetElement, Html5SchemaProvider.getCharsDtdLocation());
}
else if (rootTag != null && document.getUserData(DISABLE_ENTITY_EXPAND) == null) {
final XmlElementDescriptor descriptor = rootTag.getDescriptor();
if (descriptor != null && !(descriptor instanceof AnyXmlElementDescriptor)) {
PsiElement element = descriptor.getDeclaration();
final PsiFile containingFile = element != null ? element.getContainingFile():null;
descriptorFile = containingFile instanceof XmlFile ? (XmlFile)containingFile:null;
final PsiFile containingFile = element != null ? element.getContainingFile() : null;
descriptorFile = containingFile instanceof XmlFile ? (XmlFile)containingFile : null;
}
}
if (descriptorFile != null &&
!descriptorFile.getName().equals(((XmlFile)targetElement).getName() + ".dtd")) {
deps.add(descriptorFile);
XmlUtil.processXmlElements(
descriptorFile,
processor,
true
);
}
}
if (descriptorFile != null &&
!descriptorFile.getName().equals(((XmlFile)targetElement).getName() + ".dtd")) {
deps.add(descriptorFile);
XmlUtil.processXmlElements(
descriptorFile,
processor,
true
);
}
}
return new CachedValueProvider.Result<XmlEntityDecl>(result[0], ArrayUtil.toObjectArray(deps));
}
finally {
targetElement.putUserData(EVALUATION_IN_PROCESS, null);
}
return new CachedValueProvider.Result<XmlEntityDecl>(result[0], ArrayUtil.toObjectArray(deps));
}
});
}
private static String getDtdForEntity(XmlDoctype xmlDoctype) {
@@ -214,7 +214,7 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef {
@Override
@NotNull
public PsiReference[] getReferences() {
return ReferenceProvidersRegistry.getReferencesFromProviders(this,XmlEntityRef.class);
return ReferenceProvidersRegistry.getReferencesFromProviders(this);
}
@Override