mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
@@ -194,8 +194,7 @@ libraryLicense(name: "jgit-1.1.0", version: "1.1.0.201109151100", license: "EDL/
|
||||
libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "1.1-preview 2006-05-04 11:55:37", license: "BSD ", url: "http://www.jgoodies.com/freeware/forms/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
|
||||
libraryLicense(name: "JGoodies Looks", libraryName: "jgoodies-looks", version: "2.4.2", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
|
||||
libraryLicense(name: "JGoodies Common", libraryName: "jgoodies-common", version: "1.2.1", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
|
||||
libraryLicense(name: "JNA", libraryName: "jna", version: "3.2.4", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php")
|
||||
libraryLicense(name: "JNA", libraryName: "jna.jar", version: "3.2.7", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php")
|
||||
libraryLicense(name: "JNA", libraryName: "jna", version: "3.4.0", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php")
|
||||
libraryLicense(name: "JSch", libraryName: "JSch", version: "0.1.44", license: "BSD", url: "http://www.jcraft.com/jsch/", licenseUrl: "http://www.jcraft.com/jsch/LICENSE.txt")
|
||||
libraryLicense(name: "JUnit", libraryName: "JUnit3", version: "3.8.1", license: "CPL 1.0", url: "http://junit.org/")
|
||||
libraryLicense(name: "JUnit", libraryName: "JUnit4", version: "4.8", license: "CPL 1.0", url: "http://junit.org/")
|
||||
|
||||
@@ -323,7 +323,7 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
synchronized (myAutomakeFutures) {
|
||||
for (Map.Entry<RequestFuture, Project> entry : myAutomakeFutures.entrySet()) {
|
||||
if (entry.getValue().equals(project)) {
|
||||
entry.getKey().cancel(true);
|
||||
entry.getKey().cancel(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-3
@@ -113,8 +113,15 @@ public class LibraryDefinitionsGeneratorFactory {
|
||||
final Library library,
|
||||
final File baseDir,
|
||||
final CompositeGenerator libraryPath) {
|
||||
genLibraryContent(genOptions, library, OrderRootType.CLASSES, baseDir, libraryPath);
|
||||
}
|
||||
|
||||
public static void genLibraryContent(final GenerationOptions genOptions,
|
||||
final Library library,
|
||||
final OrderRootType rootType, final File baseDir,
|
||||
final CompositeGenerator libraryPath) {
|
||||
if (genOptions.expandJarDirectories) {
|
||||
final VirtualFile[] files = library.getFiles(OrderRootType.CLASSES);
|
||||
final VirtualFile[] files = library.getFiles(rootType);
|
||||
// note that it is assumed that directory entries inside library path are unordered
|
||||
TreeSet<String> visitedPaths = new TreeSet<String>();
|
||||
for (final VirtualFile file : files) {
|
||||
@@ -127,7 +134,7 @@ public class LibraryDefinitionsGeneratorFactory {
|
||||
}
|
||||
}
|
||||
else {
|
||||
TreeSet<String> urls = new TreeSet<String>(Arrays.asList(library.getUrls(OrderRootType.CLASSES)));
|
||||
TreeSet<String> urls = new TreeSet<String>(Arrays.asList(library.getUrls(rootType)));
|
||||
for (String url : urls) {
|
||||
File file = fileFromUrl(url);
|
||||
final String path = GenerationUtils
|
||||
@@ -136,7 +143,7 @@ public class LibraryDefinitionsGeneratorFactory {
|
||||
libraryPath.add(new PathElement(path));
|
||||
}
|
||||
else if (url.startsWith(LocalFileSystem.PROTOCOL_PREFIX)) {
|
||||
if (library.isJarDirectory(url, OrderRootType.CLASSES)) {
|
||||
if (library.isJarDirectory(url, rootType)) {
|
||||
final FileSet fileSet = new FileSet(path);
|
||||
fileSet.add(new PatternSetRef(BuildProperties.PROPERTY_LIBRARIES_PATTERNS));
|
||||
libraryPath.add(fileSet);
|
||||
|
||||
@@ -609,7 +609,7 @@ public class CompileDriver {
|
||||
if (future != null) {
|
||||
while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) {
|
||||
if (indicator.isCanceled()) {
|
||||
future.cancel(true);
|
||||
future.cancel(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>6</line>
|
||||
<description>Casting <code>t</code> to <code>Foo</code> is redundant</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>A.java</file>
|
||||
<line>5</line>
|
||||
<description>Casting <code>t</code> to <code>Foo</code> is redundant</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
abstract class Foo {
|
||||
protected int field;
|
||||
|
||||
public int f(Bar t){
|
||||
((Foo)t).field = 0;
|
||||
return ((Foo)t).field;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Bar extends Foo{}
|
||||
@@ -88,6 +88,7 @@ public class RedundantCastTest extends InspectionTestCase {
|
||||
public void testIDEADEV15170() throws Exception { doTest(); }
|
||||
|
||||
public void testIDEADEV25675() throws Exception { doTest(); }
|
||||
public void testFieldAccessOnTheLeftOfAssignment() throws Exception { doTest(); }
|
||||
|
||||
public void testNestedCast() throws Exception { doTest(); }
|
||||
public void testPrimitiveInsideSynchronized() throws Exception { doTest(); }
|
||||
|
||||
@@ -476,7 +476,7 @@ public class RedundantCastUtil {
|
||||
PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(element, PsiAssignmentExpression.class, false, PsiMember.class);
|
||||
if (assignment == null) return false;
|
||||
PsiExpression lExpression = assignment.getLExpression();
|
||||
return PsiTreeUtil.isAncestor(lExpression, element, false);
|
||||
return PsiTreeUtil.isAncestor(lExpression, element, false) && lExpression instanceof PsiArrayAccessExpression;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public class CompileServerClient extends SimpleProtobufClient<JpsServerResponseH
|
||||
protected void beforeDisconnect() {
|
||||
final ScheduledFuture<?> future = myPingFuture;
|
||||
if (future != null) {
|
||||
future.cancel(true);
|
||||
future.cancel(false);
|
||||
myPingFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
);
|
||||
while (!future.waitFor(100L, TimeUnit.MILLISECONDS)) {
|
||||
if (context.isCanceled()) {
|
||||
future.cancel(true);
|
||||
future.cancel(false);
|
||||
}
|
||||
}
|
||||
rc = future.getResponseHandler().isTerminatedSuccessfully();
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
|
||||
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.api.AsyncTaskExecutor;
|
||||
import org.jetbrains.jps.api.GlobalOptions;
|
||||
import org.jetbrains.jps.api.JpsRemoteProto;
|
||||
import org.jetbrains.jps.incremental.Paths;
|
||||
@@ -55,7 +56,22 @@ public class Server {
|
||||
myBuildsExecutor = Executors.newFixedThreadPool(MAX_SIMULTANEOUS_BUILD_SESSIONS);
|
||||
myChannelFactory = new NioServerSocketChannelFactory(threadPool, threadPool, 1);
|
||||
final ChannelRegistrar channelRegistrar = new ChannelRegistrar();
|
||||
myMessageHandler = new ServerMessageHandler(myBuildsExecutor, this);
|
||||
myMessageHandler = new ServerMessageHandler(this, new AsyncTaskExecutor() {
|
||||
@Override
|
||||
public void submit(final Runnable runnable) {
|
||||
myBuildsExecutor.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
}
|
||||
finally {
|
||||
Thread.interrupted(); // clear interrupted status before returning to pull
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
myPipelineFactory = new ChannelPipelineFactory() {
|
||||
public ChannelPipeline getPipeline() throws Exception {
|
||||
return Channels.pipeline(
|
||||
@@ -114,14 +130,12 @@ public class Server {
|
||||
}
|
||||
|
||||
private void doStop(long elapsedTime) {
|
||||
if (!myMessageHandler.hasRunningBuilds()) {
|
||||
try {
|
||||
System.out.println("Stopping compile server; reason: no pings from client received in " + elapsedTime + " ms");
|
||||
stop();
|
||||
}
|
||||
finally {
|
||||
System.exit(0);
|
||||
}
|
||||
try {
|
||||
System.out.println("Stopping compile server; reason: no pings from client received in " + elapsedTime + " ms");
|
||||
myMessageHandler.cancelAllBuildsAndClearState();
|
||||
}
|
||||
finally {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}, allowedIdlePeriod, allowedIdlePeriod, TimeUnit.MILLISECONDS);
|
||||
@@ -129,8 +143,8 @@ public class Server {
|
||||
|
||||
public void stop() {
|
||||
try {
|
||||
myScheduler.shutdownNow();
|
||||
myBuildsExecutor.shutdownNow();
|
||||
myScheduler.shutdown();
|
||||
myBuildsExecutor.shutdown();
|
||||
final ChannelGroupFuture closeFuture = myAllOpenChannels.close();
|
||||
closeFuture.awaitUninterruptibly();
|
||||
}
|
||||
@@ -162,7 +176,12 @@ public class Server {
|
||||
final Server server = new Server(systemDir);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") {
|
||||
public void run() {
|
||||
server.stop();
|
||||
try {
|
||||
server.myMessageHandler.cancelAllBuildsAndClearState();
|
||||
}
|
||||
finally {
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.RunnableFuture;
|
||||
|
||||
/**
|
||||
@@ -27,12 +26,12 @@ class ServerMessageHandler extends SimpleChannelHandler {
|
||||
|
||||
private final Map<String, SequentialTaskExecutor> myTaskExecutors = new HashMap<String, SequentialTaskExecutor>();
|
||||
private final List<Pair<RunnableFuture, CompilationTask>> myBuildsInProgress = Collections.synchronizedList(new LinkedList<Pair<RunnableFuture, CompilationTask>>());
|
||||
private final ExecutorService myBuildsExecutor;
|
||||
private final Server myServer;
|
||||
private final AsyncTaskExecutor myAsyncExecutor;
|
||||
|
||||
public ServerMessageHandler(ExecutorService buildsExecutor, Server server) {
|
||||
myBuildsExecutor = buildsExecutor;
|
||||
public ServerMessageHandler(Server server, final AsyncTaskExecutor asyncExecutor) {
|
||||
myServer = server;
|
||||
myAsyncExecutor = asyncExecutor;
|
||||
}
|
||||
|
||||
public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) throws Exception {
|
||||
@@ -87,35 +86,14 @@ class ServerMessageHandler extends SimpleChannelHandler {
|
||||
break;
|
||||
|
||||
case SHUTDOWN_COMMAND :
|
||||
myBuildsExecutor.submit(new Runnable() {
|
||||
myAsyncExecutor.submit(new Runnable() {
|
||||
public void run() {
|
||||
final List<RunnableFuture> futures = new ArrayList<RunnableFuture>();
|
||||
|
||||
synchronized (myBuildsInProgress) {
|
||||
for (Iterator<Pair<RunnableFuture, CompilationTask>> it = myBuildsInProgress.iterator(); it.hasNext(); ) {
|
||||
final Pair<RunnableFuture, CompilationTask> pair = it.next();
|
||||
it.remove();
|
||||
pair.second.cancel();
|
||||
final RunnableFuture future = pair.first;
|
||||
futures.add(future);
|
||||
future.cancel(true);
|
||||
}
|
||||
try {
|
||||
cancelAllBuildsAndClearState();
|
||||
}
|
||||
|
||||
facade.clearCahedState();
|
||||
|
||||
// wait until really stopped
|
||||
for (RunnableFuture future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
catch (ExecutionException ignored) {
|
||||
}
|
||||
finally {
|
||||
myServer.stop();
|
||||
}
|
||||
|
||||
myServer.stop();
|
||||
}
|
||||
});
|
||||
break;
|
||||
@@ -124,16 +102,24 @@ class ServerMessageHandler extends SimpleChannelHandler {
|
||||
final String projectId = fsEvent.getProjectId();
|
||||
final ProjectDescriptor pd = facade.getProjectDescriptor(projectId);
|
||||
if (pd != null) {
|
||||
final boolean wasInterrupted = Thread.interrupted();
|
||||
try {
|
||||
for (String path : fsEvent.getChangedPathsList()) {
|
||||
facade.notifyFileChanged(pd, new File(path));
|
||||
try {
|
||||
for (String path : fsEvent.getChangedPathsList()) {
|
||||
facade.notifyFileChanged(pd, new File(path));
|
||||
}
|
||||
for (String path : fsEvent.getDeletedPathsList()) {
|
||||
facade.notifyFileDeleted(pd, new File(path));
|
||||
}
|
||||
}
|
||||
for (String path : fsEvent.getDeletedPathsList()) {
|
||||
facade.notifyFileDeleted(pd, new File(path));
|
||||
finally {
|
||||
pd.release();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
pd.release();
|
||||
if (wasInterrupted) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
reply = ProtoUtil.toMessage(sessionId, ProtoUtil.createCommandCompletedEvent(null));
|
||||
@@ -149,6 +135,34 @@ class ServerMessageHandler extends SimpleChannelHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelAllBuildsAndClearState() {
|
||||
final List<RunnableFuture> futures = new ArrayList<RunnableFuture>();
|
||||
|
||||
synchronized (myBuildsInProgress) {
|
||||
for (Iterator<Pair<RunnableFuture, CompilationTask>> it = myBuildsInProgress.iterator(); it.hasNext(); ) {
|
||||
final Pair<RunnableFuture, CompilationTask> pair = it.next();
|
||||
it.remove();
|
||||
pair.second.cancel();
|
||||
final RunnableFuture future = pair.first;
|
||||
futures.add(future);
|
||||
future.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
ServerState.getInstance().clearCahedState();
|
||||
|
||||
// wait until really stopped
|
||||
for (RunnableFuture future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
catch (ExecutionException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelSession(UUID targetSessionId) {
|
||||
synchronized (myBuildsInProgress) {
|
||||
for (Iterator<Pair<RunnableFuture, CompilationTask>> it = myBuildsInProgress.iterator(); it.hasNext(); ) {
|
||||
@@ -157,7 +171,7 @@ class ServerMessageHandler extends SimpleChannelHandler {
|
||||
if (task.getSessionId().equals(targetSessionId)) {
|
||||
it.remove();
|
||||
task.cancel();
|
||||
pair.first.cancel(true);
|
||||
pair.first.cancel(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -212,12 +226,7 @@ class ServerMessageHandler extends SimpleChannelHandler {
|
||||
synchronized (myTaskExecutors) {
|
||||
SequentialTaskExecutor executor = myTaskExecutors.get(projectId);
|
||||
if (executor == null) {
|
||||
executor = new SequentialTaskExecutor(new AsyncTaskExecutor() {
|
||||
@Override
|
||||
public void submit(Runnable runnable) {
|
||||
myBuildsExecutor.submit(runnable);
|
||||
}
|
||||
});
|
||||
executor = new SequentialTaskExecutor(myAsyncExecutor);
|
||||
myTaskExecutors.put(projectId, executor);
|
||||
}
|
||||
return executor;
|
||||
|
||||
BIN
Binary file not shown.
Executable → Regular
BIN
Binary file not shown.
@@ -228,4 +228,9 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements
|
||||
public boolean excludeCompileBeforeLaunchOption() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getType() + ": " + getName();
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -366,6 +366,11 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getType() + ": " + getName();
|
||||
}
|
||||
|
||||
private class InfoProvider implements ConfigurationInfoProvider {
|
||||
private final ProgramRunner myRunner;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.projectImport.ProjectOpenedCallback;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -44,11 +45,21 @@ public class NewDirectoryProjectAction extends AnAction implements DumbAware {
|
||||
NewDirectoryProjectDialog dlg = new NewDirectoryProjectDialog(project);
|
||||
dlg.show();
|
||||
if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
|
||||
|
||||
}
|
||||
|
||||
protected Object showSettings(DirectoryProjectGenerator generator, VirtualFile baseDir)
|
||||
throws ProcessCanceledException {
|
||||
return generator.showGenerationSettings(baseDir);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Project generateProject(Project project, NewDirectoryProjectDialog dlg) {
|
||||
final DirectoryProjectGenerator generator = dlg.getProjectGenerator();
|
||||
final File location = new File(dlg.getNewProjectLocation());
|
||||
if (!location.exists() && !location.mkdirs()) {
|
||||
Messages.showErrorDialog(project, "Cannot create directory '" + location + "'", "Create Project");
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
final VirtualFile baseDir = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
|
||||
@@ -61,11 +72,10 @@ public class NewDirectoryProjectAction extends AnAction implements DumbAware {
|
||||
if (baseDir.getChildren().length > 0) {
|
||||
int rc = Messages.showYesNoDialog(project,
|
||||
"The directory '" + location +
|
||||
"' is not empty. Would you like to create a project from existing sources instead?",
|
||||
"' is not empty. Would you like to create a project from existing sources instead?",
|
||||
"Create New Project", Messages.getQuestionIcon());
|
||||
if (rc == 0) {
|
||||
PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
|
||||
return;
|
||||
return PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,15 +84,15 @@ public class NewDirectoryProjectAction extends AnAction implements DumbAware {
|
||||
Object settings = null;
|
||||
if (generator != null) {
|
||||
try {
|
||||
settings = generator.showGenerationSettings(baseDir);
|
||||
settings = showSettings(generator, baseDir);
|
||||
}
|
||||
catch (ProcessCanceledException e1) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
GeneralSettings.getInstance().setLastProjectLocation(location.getParent());
|
||||
final Object finalSettings = settings;
|
||||
PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
|
||||
return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
|
||||
@Override
|
||||
public void projectOpened(Project project, Module module) {
|
||||
if (generator != null) {
|
||||
|
||||
@@ -41,8 +41,8 @@ import java.io.File;
|
||||
public class NewDirectoryProjectDialog extends DialogWrapper {
|
||||
private JTextField myProjectNameTextField;
|
||||
private TextFieldWithBrowseButton myLocationField;
|
||||
private JPanel myRootPane;
|
||||
private JComboBox myProjectTypeComboBox;
|
||||
protected JPanel myRootPane;
|
||||
protected JComboBox myProjectTypeComboBox;
|
||||
private JPanel myProjectTypePanel;
|
||||
private JLabel myLocationLabel;
|
||||
|
||||
|
||||
+2
-2
@@ -82,7 +82,7 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
return result != null ? result : super.resolve(o, context);
|
||||
}
|
||||
|
||||
private Project getProject(ConvertContext context) {
|
||||
private static Project getProject(ConvertContext context) {
|
||||
return context.getFile().getProject();
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
return new ConverterStrategy();
|
||||
}
|
||||
|
||||
private class MyUpdateIndicesFix implements LocalQuickFix {
|
||||
private static class MyUpdateIndicesFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return MavenDomBundle.message("inspection.group");
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.indices;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.*;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
@@ -52,10 +51,7 @@ public class MavenIndex {
|
||||
private static final String UPDATE_DIR = "update";
|
||||
|
||||
private static final String DATA_DIR_PREFIX = "data";
|
||||
private static final String GROUP_IDS_FILE = "groupIds.dat";
|
||||
private static final String ARTIFACT_IDS_FILE = "artifactIds.dat";
|
||||
|
||||
private static final String VERSIONS_FILE = "versions.dat";
|
||||
private static final String ARTIFACT_IDS_MAP_FILE = "artifactIds-map.dat";
|
||||
private static final String VERSIONS_MAP_FILE = "versions-map.dat";
|
||||
|
||||
@@ -69,14 +65,14 @@ public class MavenIndex {
|
||||
private final String myRepositoryId;
|
||||
private final String myRepositoryPathOrUrl;
|
||||
private final Kind myKind;
|
||||
private volatile Long myUpdateTimestamp;
|
||||
private Long myUpdateTimestamp;
|
||||
|
||||
private volatile String myDataDirName;
|
||||
private volatile IndexData myData;
|
||||
private String myDataDirName;
|
||||
private IndexData myData;
|
||||
|
||||
private volatile String myFailureMessage;
|
||||
private String myFailureMessage;
|
||||
|
||||
private volatile boolean isBroken;
|
||||
private boolean isBroken;
|
||||
private final IndexListener myListener;
|
||||
|
||||
public MavenIndex(MavenIndexerWrapper indexer,
|
||||
@@ -128,7 +124,7 @@ public class MavenIndex {
|
||||
String timestamp = props.getProperty(TIMESTAMP_KEY);
|
||||
if (timestamp != null) myUpdateTimestamp = Long.parseLong(timestamp);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
|
||||
myDataDirName = props.getProperty(DATA_DIR_NAME_KEY);
|
||||
@@ -347,19 +343,20 @@ public class MavenIndex {
|
||||
myUpdateTimestamp = System.currentTimeMillis();
|
||||
|
||||
oldData.close(true);
|
||||
for (File each : getAllDataDirs()) {
|
||||
if (each.getName().equals(newDataDirName)) continue;
|
||||
FileUtil.delete(each);
|
||||
|
||||
File[] children = myDir.listFiles();
|
||||
if (children != null) {
|
||||
for (File each : children) {
|
||||
if (each.getName().startsWith(DATA_DIR_PREFIX) && !each.getName().equals(newDataDirName)) {
|
||||
FileUtil.delete(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doUpdateIndexData(IndexData data,
|
||||
MavenProgressIndicator progress) throws IOException, MavenServerIndexerException {
|
||||
final Set<String> groups = new THashSet<String>();
|
||||
final Set<String> groupsWithArtifacts = new THashSet<String>();
|
||||
final Set<String> groupsWithArtifactsWithVersions = new THashSet<String>();
|
||||
|
||||
final Map<String, Set<String>> groupToArtifactMap = new THashMap<String, Set<String>>();
|
||||
final Map<String, Set<String>> groupWithArtifactToVersionMap = new THashMap<String, Set<String>>();
|
||||
|
||||
@@ -382,23 +379,12 @@ public class MavenIndex {
|
||||
builder.append(groupId).append(":").append(artifactId);
|
||||
String ga = builder.toString();
|
||||
|
||||
builder.append(":").append(version);
|
||||
String gav = builder.toString();
|
||||
|
||||
groups.add(groupId);
|
||||
groupsWithArtifacts.add(ga);
|
||||
groupsWithArtifactsWithVersions.add(gav);
|
||||
|
||||
getOrCreate(groupToArtifactMap, groupId).add(artifactId);
|
||||
getOrCreate(groupWithArtifactToVersionMap, ga).add(version);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
persist(groups, data.groups);
|
||||
persist(groupsWithArtifacts, data.groupsWithArtifacts);
|
||||
persist(groupsWithArtifactsWithVersions, data.groupsWithArtifactsWithVersions);
|
||||
|
||||
persist(groupToArtifactMap, data.groupToArtifactMap);
|
||||
persist(groupWithArtifactToVersionMap, data.groupWithArtifactToVersionMap);
|
||||
}
|
||||
@@ -416,13 +402,13 @@ public class MavenIndex {
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T> void persist(Map<String, T> map, PersistentHashMap<String, T> persistentMap) throws IOException {
|
||||
private static <T> void persist(Map<String, T> map, PersistentHashMap<String, T> persistentMap) throws IOException {
|
||||
for (Map.Entry<String, T> each : map.entrySet()) {
|
||||
persistentMap.put(each.getKey(), each.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void persist(Set<String> groups, PersistentStringEnumerator persistent) throws IOException {
|
||||
private static void persist(Set<String> groups, PersistentStringEnumerator persistent) throws IOException {
|
||||
for (String each : groups) {
|
||||
persistent.enumerate(each);
|
||||
}
|
||||
@@ -448,7 +434,7 @@ public class MavenIndex {
|
||||
return new File(myDir, dataDirName);
|
||||
}
|
||||
|
||||
private File getDataContextDir(File dataDir) {
|
||||
private static File getDataContextDir(File dataDir) {
|
||||
return new File(dataDir, "context");
|
||||
}
|
||||
|
||||
@@ -456,16 +442,6 @@ public class MavenIndex {
|
||||
return MavenIndices.findAvailableDir(myDir, DATA_DIR_PREFIX, 100).getName();
|
||||
}
|
||||
|
||||
private Iterable<File> getAllDataDirs() {
|
||||
File[] children = myDir.listFiles();
|
||||
if (children == null) return ContainerUtil.emptyIterable();
|
||||
return ContainerUtil.iterate(children, new Condition<File>() {
|
||||
public boolean value(File file) {
|
||||
return file.getName().startsWith(DATA_DIR_PREFIX);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void addArtifact(final File artifactFile) {
|
||||
doIndexTask(new IndexTask<Object>() {
|
||||
public Object doTask() throws Exception {
|
||||
@@ -475,20 +451,8 @@ public class MavenIndex {
|
||||
String artifactId = id.getArtifactId();
|
||||
String version = id.getVersion();
|
||||
|
||||
myData.groups.enumerate(groupId);
|
||||
myData.hasGroupCache.put(groupId, true);
|
||||
|
||||
String groupWithArtifact = groupId + ":" + artifactId;
|
||||
|
||||
myData.groupsWithArtifacts.enumerate(groupWithArtifact);
|
||||
myData.hasArtifactCache.put(groupWithArtifact, true);
|
||||
addToCache(myData.groupToArtifactMap, groupId, artifactId);
|
||||
|
||||
String groupWithArtifactWithVersion = groupWithArtifact + ":" + version;
|
||||
|
||||
myData.groupsWithArtifactsWithVersions.enumerate(groupWithArtifactWithVersion);
|
||||
myData.hasVersionCache.put(groupWithArtifactWithVersion, true);
|
||||
addToCache(myData.groupWithArtifactToVersionMap, groupWithArtifact, version);
|
||||
addToCache(myData.groupWithArtifactToVersionMap, groupId + ":" + artifactId, version);
|
||||
myData.flush();
|
||||
|
||||
return null;
|
||||
@@ -496,24 +460,17 @@ public class MavenIndex {
|
||||
}, null);
|
||||
}
|
||||
|
||||
private void addToCache(PersistentHashMap<String, Set<String>> cache, String key, String value) throws IOException {
|
||||
private static void addToCache(PersistentHashMap<String, Set<String>> cache, String key, String value) throws IOException {
|
||||
Set<String> values = cache.get(key);
|
||||
if (values == null) values = new THashSet<String>();
|
||||
values.add(value);
|
||||
cache.put(key, values);
|
||||
}
|
||||
|
||||
public synchronized Set<String> getGroupIds() {
|
||||
return doIndexTask(new IndexTask<Set<String>>() {
|
||||
public Set<String> doTask() throws Exception {
|
||||
final Set<String> result = new THashSet<String>();
|
||||
myData.groups.traverseAllRecords(new PersistentEnumerator.RecordsProcessor() {
|
||||
public boolean process(int record) throws IOException {
|
||||
result.add(myData.groups.valueOf(record));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
public synchronized Collection<String> getGroupIds() {
|
||||
return doIndexTask(new IndexTask<Collection<String>>() {
|
||||
public Collection<String> doTask() throws Exception {
|
||||
return myData.groupToArtifactMap.getAllDataObjects(null);
|
||||
}
|
||||
}, Collections.<String>emptySet());
|
||||
}
|
||||
@@ -537,38 +494,29 @@ public class MavenIndex {
|
||||
}
|
||||
|
||||
public synchronized boolean hasGroupId(String groupId) {
|
||||
return hasValue(myData.groups, myData.hasGroupCache, groupId);
|
||||
return hasValue(myData.groupToArtifactMap, groupId);
|
||||
}
|
||||
|
||||
public synchronized boolean hasArtifactId(String groupId, String artifactId) {
|
||||
return hasValue(myData.groupsWithArtifacts,
|
||||
myData.hasArtifactCache,
|
||||
groupId + ":" + artifactId);
|
||||
return hasValue(myData.groupWithArtifactToVersionMap, groupId + ":" + artifactId);
|
||||
}
|
||||
|
||||
public synchronized boolean hasVersion(String groupId, String artifactId, String version) {
|
||||
return hasValue(myData.groupsWithArtifactsWithVersions,
|
||||
myData.hasVersionCache,
|
||||
groupId + ":" + artifactId + ":" + version);
|
||||
}
|
||||
|
||||
private boolean hasValue(final PersistentStringEnumerator set, Map<String, Boolean> cache, final String value) {
|
||||
Boolean cached = cache.get(value);
|
||||
if (cached != null) return cached;
|
||||
|
||||
boolean result = doIndexTask(new IndexTask<Boolean>() {
|
||||
public synchronized boolean hasVersion(final String groupId, final String artifactId, final String version) {
|
||||
return doIndexTask(new IndexTask<Boolean>() {
|
||||
@Override
|
||||
public Boolean doTask() throws Exception {
|
||||
return !set.traverseAllRecords(new PersistentEnumerator.RecordsProcessor() {
|
||||
public boolean process(int record) throws IOException {
|
||||
if (value.equals(set.valueOf(record))) return false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
Set<String> set = myData.groupWithArtifactToVersionMap.get(groupId + ":" + artifactId);
|
||||
return set != null && set.contains(version);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
private boolean hasValue(final PersistentHashMap<String, ?> map, final String value) {
|
||||
return doIndexTask(new IndexTask<Boolean>() {
|
||||
public Boolean doTask() throws Exception {
|
||||
return map.tryEnumerate(value) != 0;
|
||||
}
|
||||
}, false).booleanValue();
|
||||
|
||||
cache.put(value, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public synchronized Set<MavenArtifactInfo> search(final Query query, final int maxResult) {
|
||||
@@ -614,25 +562,13 @@ public class MavenIndex {
|
||||
}
|
||||
|
||||
private class IndexData {
|
||||
final PersistentStringEnumerator groups;
|
||||
final PersistentStringEnumerator groupsWithArtifacts;
|
||||
final PersistentStringEnumerator groupsWithArtifactsWithVersions;
|
||||
|
||||
final PersistentHashMap<String, Set<String>> groupToArtifactMap;
|
||||
final PersistentHashMap<String, Set<String>> groupWithArtifactToVersionMap;
|
||||
|
||||
final Map<String, Boolean> hasGroupCache = new THashMap<String, Boolean>();
|
||||
final Map<String, Boolean> hasArtifactCache = new THashMap<String, Boolean>();
|
||||
final Map<String, Boolean> hasVersionCache = new THashMap<String, Boolean>();
|
||||
|
||||
private final int indexId;
|
||||
|
||||
public IndexData(File dir) throws MavenIndexException {
|
||||
try {
|
||||
groups = new PersistentStringEnumerator(new File(dir, GROUP_IDS_FILE));
|
||||
groupsWithArtifacts = new PersistentStringEnumerator(new File(dir, ARTIFACT_IDS_FILE));
|
||||
groupsWithArtifactsWithVersions = new PersistentStringEnumerator(new File(dir, VERSIONS_FILE));
|
||||
|
||||
groupToArtifactMap = createPersistentMap(new File(dir, ARTIFACT_IDS_MAP_FILE));
|
||||
groupWithArtifactToVersionMap = createPersistentMap(new File(dir, VERSIONS_MAP_FILE));
|
||||
|
||||
@@ -663,17 +599,13 @@ public class MavenIndex {
|
||||
if (exceptions[0] == null) exceptions[0] = new MavenIndexException(e);
|
||||
}
|
||||
|
||||
safeClose(groups, exceptions);
|
||||
safeClose(groupsWithArtifacts, exceptions);
|
||||
safeClose(groupsWithArtifactsWithVersions, exceptions);
|
||||
|
||||
safeClose(groupToArtifactMap, exceptions);
|
||||
safeClose(groupWithArtifactToVersionMap, exceptions);
|
||||
|
||||
if (exceptions[0] != null) throw exceptions[0];
|
||||
}
|
||||
|
||||
private void safeClose(Closeable enumerator, MavenIndexException[] exceptions) {
|
||||
private void safeClose(@Nullable Closeable enumerator, MavenIndexException[] exceptions) {
|
||||
try {
|
||||
if (enumerator != null) enumerator.close();
|
||||
}
|
||||
@@ -684,10 +616,6 @@ public class MavenIndex {
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
groups.force();
|
||||
groupsWithArtifacts.force();
|
||||
groupsWithArtifactsWithVersions.force();
|
||||
|
||||
groupToArtifactMap.force();
|
||||
groupWithArtifactToVersionMap.force();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.idea.maven.indices;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.project.MavenGeneralSettings;
|
||||
import org.jetbrains.idea.maven.server.MavenIndexerWrapper;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
@@ -45,8 +46,6 @@ public class MavenIndices {
|
||||
}
|
||||
|
||||
private void load() {
|
||||
if (!myIndicesDir.exists()) return;
|
||||
|
||||
File[] indices = myIndicesDir.listFiles();
|
||||
if (indices == null) return;
|
||||
Arrays.sort(indices);
|
||||
@@ -90,6 +89,7 @@ public class MavenIndices {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MavenIndex find(String repositoryId, String repositoryPathOrUrl, MavenIndex.Kind kind) {
|
||||
for (MavenIndex each : myIndices) {
|
||||
if (each.isFor(kind, repositoryId, repositoryPathOrUrl)) return each;
|
||||
@@ -107,8 +107,8 @@ public class MavenIndices {
|
||||
String name = prefix + i;
|
||||
File f = new File(parent, name);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
assert f.exists();
|
||||
boolean createSuccessFull = f.mkdirs();
|
||||
assert createSuccessFull || f.exists();
|
||||
return f;
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public class MavenIndices {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateOrRepair(MavenIndex index, boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
public static void updateOrRepair(MavenIndex index, boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
throws MavenProcessCanceledException {
|
||||
index.updateOrRepair(fullUpdate, settings, progress);
|
||||
}
|
||||
|
||||
+2
-2
@@ -232,7 +232,7 @@ public class MavenIndicesManager {
|
||||
|
||||
myWaitingIndices.addAll(toSchedule);
|
||||
}
|
||||
|
||||
if (toSchedule.isEmpty()) return;
|
||||
myUpdatingQueue.run(new Task.Backgroundable(projectOrNull, IndicesBundle.message("maven.indices.updating"), true) {
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
@@ -288,7 +288,7 @@ public class MavenIndicesManager {
|
||||
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
settings = project.isDisposed() ? null : MavenProjectsManager.getInstance(project).getGeneralSettings();
|
||||
settings = project.isDisposed() ? null : MavenProjectsManager.getInstance(project).getGeneralSettings().clone();
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
|
||||
@@ -244,7 +244,7 @@ public class MavenIndicesTest extends MavenIndicesTestCase {
|
||||
assertUnorderedElementsAreEqual(i2.getGroupIds(), "jmock");
|
||||
|
||||
shutdownIndices();
|
||||
damageFile(i1, "groupIds.dat", true);
|
||||
damageFile(i1, "artifactIds-map.dat", true);
|
||||
initIndices();
|
||||
|
||||
assertEquals(2, myIndices.getIndices().size());
|
||||
@@ -307,7 +307,7 @@ public class MavenIndicesTest extends MavenIndicesTestCase {
|
||||
myIndices.updateOrRepair(index, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
shutdownIndices();
|
||||
damageFile(index, "groupIds.dat", false);
|
||||
damageFile(index, "artifactIds-map.dat", false);
|
||||
initIndices();
|
||||
|
||||
index = myIndices.getIndices().get(0);
|
||||
|
||||
Binary file not shown.
@@ -37,15 +37,7 @@
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/jna.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="jna" level="project" />
|
||||
<orderEntry type="module-library" scope="RUNTIME">
|
||||
<library>
|
||||
<CLASSES>
|
||||
@@ -102,7 +94,7 @@
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/Javahl.jar!/" />
|
||||
<root url="jar://$MODULE_DIR$/lib/javahl.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
|
||||
Reference in New Issue
Block a user