Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2015-09-22 00:09:46 +02:00
85 changed files with 892 additions and 781 deletions
+3 -3
View File
@@ -1,13 +1,13 @@
<component name="libraryTable">
<library name="jna">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jna-utils.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/jna.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/jna-platform.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/jna-src.zip!/src" />
<root url="jar://$PROJECT_DIR$/lib/src/jna-src.zip!/contrib/platform/src" />
<root url="jar://$PROJECT_DIR$/lib/src/jna.zip!/" />
<root url="jar://$PROJECT_DIR$/lib/src/jna-platform.zip!/" />
</SOURCES>
</library>
</component>
+11 -6
View File
@@ -10,12 +10,17 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-0.0.6/jsch-agent-proxy-core/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-0.0.6/jsch-agent-proxy-pageant/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-0.0.6/jsch-agent-proxy-sshagent/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-0.0.6/jsch-agent-proxy-usocket-nc/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-0.0.6/jsch-agent-proxy-usocket-jna/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-0.0.6/jsch-agent-proxy-connector-factory/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/examples/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-connector-factory/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-core/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-jsch/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-pageant/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-sshagent/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-sshj/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-svnkit-trilead-ssh2/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-usocket-jna/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-usocket-junixsocket/src/main/java" />
<root url="jar://$PROJECT_DIR$/lib/src/jsch-agent-proxy.zip!/jsch-agent-proxy-usocket-nc/src/main/java" />
</SOURCES>
</library>
</component>
+2 -2
View File
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="pty4j">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/pty4j-0.4.22.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/pty4j-0.4.23.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/pty4j-0.4.22-src.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/src/pty4j-0.4.23-src.jar!/" />
</SOURCES>
</library>
</component>
+1 -1
View File
@@ -41,7 +41,7 @@
<include name="guava*.jar"/>
<include name="picocontainer.jar"/>
<include name="jna.jar"/>
<include name="jna-utils.jar"/>
<include name="jna-platform.jar"/>
<include name="oromatcher.jar"/>
<include name="snappy-in-java-*.jar"/>
<include name="cli-parser-*.jar"/>
+4 -4
View File
@@ -199,10 +199,10 @@ libraryLicense(name: "javawriter", libraryName: "javawriter", license: "Apache 2
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.4.0", 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: "4.1.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.52", license: "BSD", url: "http://www.jcraft.com/jsch/", licenseUrl: "http://www.jcraft.com/jsch/LICENSE.txt")
libraryLicense(name: "jsch-agent-proxy", libraryName: "jsch-agent-proxy", version: "0.0.6", license: "BSD", url: "https://github.com/ymnk/jsch-agent-proxy", licenseUrl: "https://github.com/ymnk/jsch-agent-proxy/blob/master/LICENSE.txt")
libraryLicense(name: "jsch-agent-proxy for svnkit trilead", libraryName: "jsch.agentproxy.svnkit-trilead-ssh2.jar", version: "0.0.6", license: "BSD", url: "https://github.com/ymnk/jsch-agent-proxy", licenseUrl: "https://github.com/ymnk/jsch-agent-proxy/blob/master/LICENSE.txt")
libraryLicense(name: "jsch-agent-proxy", libraryName: "jsch-agent-proxy", version: "0.0.7", license: "BSD", url: "https://github.com/ymnk/jsch-agent-proxy", licenseUrl: "https://github.com/ymnk/jsch-agent-proxy/blob/master/LICENSE.txt")
libraryLicense(name: "jsch-agent-proxy for svnkit trilead", libraryName: "jsch.agentproxy.svnkit-trilead-ssh2.jar", version: "0.0.7", license: "BSD", url: "https://github.com/ymnk/jsch-agent-proxy", licenseUrl: "https://github.com/ymnk/jsch-agent-proxy/blob/master/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.11", license: "CPL 1.0", url: "http://junit.org/")
libraryLicense(name: "Log4j", libraryName: "Log4J", version: "1.2.17", license: "Apache 2.0", url: "http://logging.apache.org/log4j/1.2/index.html", licenseUrl: "http://logging.apache.org/license.html")
@@ -242,7 +242,7 @@ libraryLicense(name: "Saxon-6.5.5", version: "6.5.5", license: "Mozilla Public L
libraryLicense(name: "Sonatype Nexus: Indexer", libraryName: "nexus-indexer-1.2.3.jar", version: "1.2.3", license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
libraryLicense(name: "Sonatype Nexus: Indexer", libraryName: "nexus-indexer-3.0.4.jar", version: "3.0.4", license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
libraryLicense(name: "Sonatype Nexus Indexer Artifact", libraryName: "nexus-indexer-artifact-1.0.1.jar", version: "1.0.1", license: "Eclipse Public License v1.0", url: "http://nexus.sonatype.org/", licenseUrl: "http://www.eclipse.org/org/documents/epl-v10.html")
libraryLicense(name: "SVNKit", libraryName: "svnkit.jar", version: "1.7.11", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html")
libraryLicense(name: "SVNKit", libraryName: "svnkit.jar", version: "1.8.7", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html")
libraryLicense(name: "Sequence", libraryName: "sequence-library.jar", version: "bundled with SVNKit", license: "BSD (see LICENSE.txt in sequence-library.jar)", url:"http://www.syntevo.com")
libraryLicense(name: "swingx", libraryName: "swingx", version: "1.6.2", license: "LGPL 2.1", url: "http://java.net/downloads/swingx/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php")
libraryLicense(name: "TestNG", version: "6.9 snapshot", license: "Apache 2.0", url: "http://testng.org/doc/", licenseUrl: "http://code.google.com/p/testng/")
+1
View File
@@ -28,6 +28,7 @@
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="java-analysis-impl" />
<orderEntry type="module" module-name="built-in-server" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
</component>
<component name="copyright">
<Base>
@@ -1,39 +0,0 @@
package org.jetbrains.builtInWebServer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.artifacts.ArtifactManager;
import com.intellij.util.PairFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
final class ArtifactWebServerRootsProvider extends PrefixlessWebServerRootsProvider {
@Nullable
@Override
public PathInfo resolve(@NotNull String path, @NotNull Project project, @NotNull PairFunction<String, VirtualFile, VirtualFile> resolver) {
for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
VirtualFile root = artifact.getOutputFile();
if (root != null) {
VirtualFile file = root.findFileByRelativePath(path);
if (file != null) {
return new PathInfo(file, root);
}
}
}
return null;
}
@Nullable
@Override
public PathInfo getRoot(@NotNull VirtualFile file, @NotNull Project project) {
for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
VirtualFile root = artifact.getOutputFile();
if (root != null && VfsUtilCore.isAncestor(root, file, true)) {
return new PathInfo(file, root);
}
}
return null;
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.builtInWebServer
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.packaging.artifacts.ArtifactManager
internal class ArtifactWebServerRootsProvider : PrefixlessWebServerRootsProvider() {
override fun resolve(path: String, project: Project, resolver: FileResolver): PathInfo? {
for (artifact in ArtifactManager.getInstance(project).artifacts) {
val root = artifact.outputFile ?: continue
return resolver.resolve(path, root)
}
return null
}
override fun getPathInfo(file: VirtualFile, project: Project): PathInfo? {
for (artifact in ArtifactManager.getInstance(project).artifacts) {
val root = artifact.outputFile ?: continue
if (VfsUtilCore.isAncestor(root, file, true)) {
return PathInfo(null, file, root)
}
}
return null
}
}
@@ -22,6 +22,7 @@ package com.intellij.debugger.jdi;
import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
@@ -278,6 +279,14 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
return myVirtualMachine.eventRequestManager();
}
/**
* @deprecated use {@link #mirrorOfVoid()} instead
*/
@Deprecated
public VoidValue mirrorOf() throws EvaluateException {
return mirrorOfVoid();
}
public VoidValue mirrorOfVoid() {
return myVirtualMachine.mirrorOfVoid();
}
@@ -137,7 +137,7 @@ public class TestDiscoveryExtension extends RunConfigurationExtension {
@Override
public boolean isListenerDisabled(RunConfigurationBase configuration, Object listener, RunnerSettings runnerSettings) {
return !(listener instanceof TestDiscoveryListener) || runnerSettings != null || !isApplicableFor(configuration);
return listener instanceof TestDiscoveryListener && (runnerSettings != null || !isApplicableFor(configuration));
}
@Override
@@ -79,7 +79,7 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element);
final PsiElement firstChild = element.getFirstChild();
if (interfaceMethod != null && firstChild != null) {
return createSuperMethodLineMarkerInfo(firstChild, AllIcons.Gutter.ImplementingMethod, Pass.UPDATE_ALL);
return createSuperMethodLineMarkerInfo(firstChild, AllIcons.Gutter.ImplementingFunctional, Pass.UPDATE_ALL);
}
if (myDaemonSettings.SHOW_METHOD_SEPARATORS && firstChild == null) {
@@ -114,7 +114,7 @@ public class JavaDocExternalFilter extends AbstractExternalFilter {
String builtInServer = "http://localhost:" + BuiltInServerOptions.getInstance().getEffectiveBuiltInServerPort() + "/" + myProject.getName() + "/";
if (docURL.startsWith(builtInServer)) {
int refPosition = docURL.lastIndexOf('#');
VirtualFile file = WebServerPathToFileManager.getInstance(myProject).get(
VirtualFile file = WebServerPathToFileManager.getInstance(myProject).findVirtualFile(
docURL.substring(builtInServer.length(), refPosition < builtInServer.length() ? docURL.length() : refPosition)
);
if (file != null) {
@@ -1004,7 +1004,7 @@ public class ControlFlowUtil {
if (isLeaf(nextOffset)) {
exitPoints[offset].add(offset);
}
else {
else if (exitPoints[nextOffset] != null) {
exitPoints[offset].addAll(exitPoints[nextOffset].toArray());
}
}
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -30,8 +30,8 @@ jgoodies-common-1.2.1.jar
jgoodies-forms.jar
jgoodies-looks-2.4.2.jar
jh.jar
jna-utils.jar
jna.jar
jna-platform.jar
jsch-0.1.52.jar
jsch.agentproxy.connector-factory.jar
jsch.agentproxy.core.jar
@@ -56,7 +56,7 @@ oromatcher.jar
picocontainer.jar
protobuf-2.5.0.jar
proxy-vole_20131209.jar
pty4j-0.4.22.jar
pty4j-0.4.23.jar
purejavacomm.jar
resolver.jar
rhino-js-1_7R4.jar
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
@@ -197,7 +197,7 @@ public class Main {
// always delete previous patch copy
File patchCopy = new File(tempDir, patchFileName + "_copy");
File log4jCopy = new File(tempDir, "log4j.jar." + platform + "_copy");
File jnaUtilsCopy = new File(tempDir, "jna-utils.jar." + platform + "_copy");
File jnaUtilsCopy = new File(tempDir, "jna-platform.jar." + platform + "_copy");
File jnaCopy = new File(tempDir, "jna.jar." + platform + "_copy");
if (!FileUtilRt.delete(patchCopy) || !FileUtilRt.delete(log4jCopy) || !FileUtilRt.delete(jnaUtilsCopy) || !FileUtilRt.delete(jnaCopy)) {
throw new IOException("Cannot delete temporary files in " + tempDir);
@@ -209,8 +209,8 @@ public class Main {
File log4j = new File(PathManager.getLibPath(), "log4j.jar");
if (!log4j.exists()) throw new IOException("Log4J is missing: " + log4j);
File jnaUtils = new File(PathManager.getLibPath(), "jna-utils.jar");
if (!jnaUtils.exists()) throw new IOException("jna-utils.jar is missing: " + jnaUtils);
File jnaUtils = new File(PathManager.getLibPath(), "jna-platform.jar");
if (!jnaUtils.exists()) throw new IOException("jna-platform.jar is missing: " + jnaUtils);
File jna = new File(PathManager.getLibPath(), "jna.jar");
if (!jna.exists()) throw new IOException("jna is missing: " + jna);
@@ -10,5 +10,7 @@
<orderEntry type="module" module-name="core-api" />
<orderEntry type="library" name="Netty" level="project" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="module" module-name="platform-api" />
</component>
</module>
@@ -1,59 +0,0 @@
package org.jetbrains.builtInWebServer;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PathInfo {
private final VirtualFile child;
private final VirtualFile root;
private final boolean isLibrary;
String moduleName;
private String computedPath;
public PathInfo(@NotNull VirtualFile child, @NotNull VirtualFile root, @Nullable String moduleName, boolean isLibrary) {
this.child = child;
this.root = root;
this.moduleName = moduleName;
this.isLibrary = isLibrary;
}
public PathInfo(@NotNull VirtualFile child, @NotNull VirtualFile root) {
this(child, root, null, false);
}
@NotNull
public VirtualFile getChild() {
return child;
}
@NotNull
public VirtualFile getRoot() {
return root;
}
@Nullable
public String getModuleName() {
return moduleName;
}
@NotNull
public String getPath() {
if (computedPath == null) {
StringBuilder builder = new StringBuilder();
if (moduleName != null) {
builder.append(moduleName).append('/');
}
if (isLibrary) {
builder.append(root.getName()).append('/');
}
computedPath = builder.append(VfsUtilCore.getRelativePath(child, root, '/')).toString();
}
return computedPath;
}
}
@@ -0,0 +1,40 @@
package org.jetbrains.builtInWebServer
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.fileTypes.FileTypeManager
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import java.io.File
class PathInfo(val ioFile: File?, val file: VirtualFile?, val root: VirtualFile, moduleName: String? = null, private val isLibrary: Boolean = false) {
var moduleName: String? = moduleName
set
val path: String by lazy {
val builder = StringBuilder()
if (moduleName != null) {
builder.append(moduleName).append('/')
}
if (isLibrary) {
builder.append(root.name).append('/')
}
if (file == null) {
builder.append(FileUtilRt.getRelativePath(FileUtilRt.toSystemIndependentName(ioFile!!.path), root.path, '/')).toString()
}
else {
builder.append(VfsUtilCore.getRelativePath(file, root, '/')).toString()
}
}
val isValid: Boolean
get() = if (ioFile == null) file!!.isValid else ioFile.exists()
val name: String
get() = if (ioFile == null) file!!.name else ioFile.name
val fileType: FileType
get() = if (ioFile == null) file!!.fileType else FileTypeManager.getInstance().getFileTypeByFileName(ioFile.name)
}
@@ -13,7 +13,7 @@ public abstract class WebServerRootsProvider {
public abstract PathInfo resolve(@NotNull String path, @NotNull Project project);
@Nullable
public abstract PathInfo getRoot(@NotNull VirtualFile file, @NotNull Project project);
public abstract PathInfo getPathInfo(@NotNull VirtualFile file, @NotNull Project project);
public boolean isClearCacheOnFileContentChanged(@NotNull VirtualFile file) {
return false;
@@ -21,26 +21,16 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtilRt
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.PathUtilRt
import com.intellij.util.UriUtil
import com.intellij.util.io.URLUtil
import com.intellij.util.net.NetUtils
import io.netty.buffer.ByteBufUtf8Writer
import io.netty.channel.Channel
import io.netty.channel.ChannelFutureListener
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.http.*
import io.netty.handler.stream.ChunkedStream
import org.jetbrains.builtInWebServer.ssi.SsiExternalResolver
import org.jetbrains.builtInWebServer.ssi.SsiProcessor
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.HttpHeaderNames
import io.netty.handler.codec.http.HttpMethod
import io.netty.handler.codec.http.QueryStringDecoder
import org.jetbrains.ide.HttpRequestHandler
import org.jetbrains.io.FileResponses
import org.jetbrains.io.Responses
import org.jetbrains.io.Responses.addKeepAliveIfNeed
import java.io.File
import java.net.InetAddress
import java.net.UnknownHostException
@@ -124,7 +114,7 @@ class BuiltInWebServer : HttpRequestHandler() {
}
}
override fun isSupported(request: FullHttpRequest) = super.isSupported(request) || request.method() === HttpMethod.POST
override fun isSupported(request: FullHttpRequest) = super.isSupported(request) || request.method() == HttpMethod.POST
override fun process(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): Boolean {
var host = request.headers().getAsString(HttpHeaderNames.HOST)
@@ -156,12 +146,12 @@ class BuiltInWebServer : HttpRequestHandler() {
}
}
public fun compareNameAndProjectBasePath(projectName: String, project: Project): Boolean {
fun compareNameAndProjectBasePath(projectName: String, project: Project): Boolean {
val basePath = project.basePath
return basePath != null && basePath.length() > projectName.length() && basePath.endsWith(projectName) && basePath.charAt(basePath.length() - projectName.length() - 1) == '/'
}
public fun findIndexFile(basedir: VirtualFile): VirtualFile? {
fun findIndexFile(basedir: VirtualFile): VirtualFile? {
val children = basedir.children
if (children == null || children.isEmpty()) {
return null
@@ -189,7 +179,7 @@ public fun findIndexFile(basedir: VirtualFile): VirtualFile? {
return null
}
public fun isOwnHostName(host: String): Boolean {
fun isOwnHostName(host: String): Boolean {
if (NetUtils.isLocalhost(host)) {
return true
}
@@ -208,93 +198,4 @@ public fun isOwnHostName(host: String): Boolean {
catch (ignored: UnknownHostException) {
return false
}
}
private class StaticFileHandler : WebServerFileHandler() {
private var ssiProcessor: SsiProcessor? = null
override fun process(file: VirtualFile, canonicalRequestPath: CharSequence, project: Project, request: FullHttpRequest, channel: Channel, isCustomHost: Boolean): Boolean {
if (file.isInLocalFileSystem) {
val nameSequence = file.nameSequence
//noinspection SpellCheckingInspection
if (StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtml") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".stm") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtm")) {
processSsi(file, canonicalRequestPath, project, request, channel, isCustomHost)
return true
}
val ioFile = VfsUtilCore.virtualToIoFile(file)
if (hasAccess(ioFile)) {
FileResponses.sendFile(request, channel, ioFile)
}
else {
Responses.sendStatus(HttpResponseStatus.FORBIDDEN, channel, request)
}
}
else {
val response = FileResponses.prepareSend(request, channel, file.timeStamp, file.path) ?: return true
val keepAlive = addKeepAliveIfNeed(response, request)
if (request.method() !== HttpMethod.HEAD) {
HttpUtil.setContentLength(response, file.length)
}
channel.write(response)
if (request.method() != HttpMethod.HEAD) {
channel.write(ChunkedStream(file.inputStream))
}
val future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
if (!keepAlive) {
future.addListener(ChannelFutureListener.CLOSE)
}
}
return true
}
private fun processSsi(file: VirtualFile, canonicalRequestPath: CharSequence, project: Project, request: FullHttpRequest, channel: Channel, isCustomHost: Boolean) {
var path = PathUtilRt.getParentPath(canonicalRequestPath.toString())
if (!isCustomHost) {
// remove project name - SSI resolves files only inside current project
path = path.substring(path.indexOf('/', 1) + 1)
}
if (ssiProcessor == null) {
ssiProcessor = SsiProcessor(false)
}
val buffer = channel.alloc().ioBuffer()
val keepAlive: Boolean
var releaseBuffer = true
try {
val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.parent), VfsUtilCore.loadText(file), file.timeStamp, ByteBufUtf8Writer(buffer))
val response = FileResponses.prepareSend(request, channel, lastModified, file.path) ?: return
keepAlive = addKeepAliveIfNeed(response, request)
if (request.method() !== HttpMethod.HEAD) {
HttpUtil.setContentLength(response, buffer.readableBytes().toLong())
}
channel.write(response)
if (request.method() !== HttpMethod.HEAD) {
releaseBuffer = false
channel.write(buffer)
}
}
finally {
if (releaseBuffer) {
buffer.release()
}
}
val future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
if (!keepAlive) {
future.addListener(ChannelFutureListener.CLOSE)
}
}
// deny access to .htaccess files
private fun hasAccess(result: File) = !result.isDirectory && result.canRead() && !(result.isHidden || result.name.startsWith(".ht"))
}
@@ -1,103 +0,0 @@
/*
* 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.builtInWebServer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.io.Responses;
final class DefaultWebServerPathHandler extends WebServerPathHandler {
@Override
public boolean process(@NotNull String path,
@NotNull Project project,
@NotNull FullHttpRequest request,
@NotNull ChannelHandlerContext context,
@Nullable String projectName,
@NotNull String decodedRawPath,
boolean isCustomHost) {
Channel channel = context.channel();
WebServerPathToFileManager pathToFileManager = WebServerPathToFileManager.getInstance(project);
VirtualFile result = pathToFileManager.pathToFileCache.getIfPresent(path);
boolean indexUsed = false;
if (result == null || !result.isValid()) {
result = pathToFileManager.findByRelativePath(project, path);
if (result == null) {
if (path.isEmpty()) {
Responses.sendStatus(HttpResponseStatus.NOT_FOUND, channel, "Index file doesn't exist.", request);
return true;
}
else {
return false;
}
}
else if (result.isDirectory()) {
if (!endsWithSlash(decodedRawPath)) {
redirectToDirectory(request, channel, isCustomHost ? path : (projectName + '/' + path));
return true;
}
result = BuiltInWebServerPackage.findIndexFile(result);
if (result == null) {
Responses.sendStatus(HttpResponseStatus.NOT_FOUND, channel, "Index file doesn't exist.", request);
return true;
}
indexUsed = true;
}
pathToFileManager.pathToFileCache.put(path, result);
}
else if (!path.endsWith(result.getName())) {
if (endsWithSlash(decodedRawPath)) {
indexUsed = true;
}
else {
// FallbackResource feature in action, /login requested, /index.php retrieved, we must not redirect /login to /login/
if (path.endsWith(result.getParent().getName())) {
redirectToDirectory(request, channel, isCustomHost ? path : (projectName + '/' + path));
return true;
}
}
}
StringBuilder canonicalRequestPath = new StringBuilder();
canonicalRequestPath.append('/');
if (!isCustomHost) {
canonicalRequestPath.append(projectName).append('/');
}
canonicalRequestPath.append(path);
if (indexUsed) {
canonicalRequestPath.append('/').append(result.getName());
}
for (WebServerFileHandler fileHandler : WebServerFileHandler.EP_NAME.getExtensions()) {
try {
if (fileHandler.process(result, canonicalRequestPath, project, request, channel, isCustomHost)) {
return true;
}
}
catch (Throwable e) {
BuiltInWebServer.LOG.error(e);
}
}
return false;
}
}
@@ -0,0 +1,108 @@
/*
* 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.builtInWebServer
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.util.PathUtilRt
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.HttpResponseStatus
import org.jetbrains.io.Responses
private class DefaultWebServerPathHandler : WebServerPathHandler() {
override fun process(path: String,
project: Project,
request: FullHttpRequest,
context: ChannelHandlerContext,
projectName: String?,
decodedRawPath: String,
isCustomHost: Boolean): Boolean {
val channel = context.channel()
val pathToFileManager = WebServerPathToFileManager.getInstance(project)
var pathInfo = pathToFileManager.pathToInfoCache.getIfPresent(path)
var indexUsed = false
if (pathInfo == null || !pathInfo.isValid) {
pathInfo = pathToFileManager.doFindByRelativePath(path)
if (pathInfo == null) {
if (path.isEmpty()) {
Responses.sendStatus(HttpResponseStatus.NOT_FOUND, channel, "Index file doesn't exist.", request)
return true
}
else {
return false
}
}
else {
var virtualFile = pathInfo.file
val isDirectory = if (virtualFile == null) pathInfo.ioFile!!.isDirectory else virtualFile.isDirectory
if (isDirectory) {
if (!WebServerPathHandler.endsWithSlash(decodedRawPath)) {
WebServerPathHandler.redirectToDirectory(request, channel, if (isCustomHost) path else (projectName + '/' + path))
return true
}
if (virtualFile == null) {
virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(pathInfo.ioFile!!)
}
virtualFile = if (virtualFile == null) null else findIndexFile(virtualFile)
if (virtualFile == null) {
Responses.sendStatus(HttpResponseStatus.NOT_FOUND, channel, "Index file doesn't exist.", request)
return true
}
indexUsed = true
}
}
pathToFileManager.pathToInfoCache.put(path, pathInfo)
}
else if (!path.endsWith(pathInfo.name)) {
if (WebServerPathHandler.endsWithSlash(decodedRawPath)) {
indexUsed = true
}
else {
// FallbackResource feature in action, /login requested, /index.php retrieved, we must not redirect /login to /login/
if (path.endsWith(PathUtilRt.getFileName(PathUtilRt.getParentPath(pathInfo.path)))) {
WebServerPathHandler.redirectToDirectory(request, channel, if (isCustomHost) path else (projectName + '/' + path))
return true
}
}
}
val canonicalRequestPath = StringBuilder()
canonicalRequestPath.append('/')
if (!isCustomHost) {
canonicalRequestPath.append(projectName).append('/')
}
canonicalRequestPath.append(path)
if (indexUsed) {
canonicalRequestPath.append('/').append(pathInfo.name)
}
for (fileHandler in WebServerFileHandler.EP_NAME.extensions) {
try {
if (fileHandler.process(pathInfo, canonicalRequestPath, project, request, channel, isCustomHost)) {
return true
}
}
catch (e: Throwable) {
BuiltInWebServer.LOG.error(e)
}
}
return false
}
}
@@ -15,7 +15,6 @@
*/
package org.jetbrains.builtInWebServer
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
@@ -34,7 +33,6 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.PairFunction
import com.intellij.util.PlatformUtils
import com.intellij.util.Processor
@@ -43,18 +41,11 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
var effectivePath = path
if (PlatformUtils.isIntelliJ()) {
val index = effectivePath.indexOf('/')
if (index > 0 && !effectivePath.regionMatches(0, project.getName(), 0, index, !SystemInfo.isFileSystemCaseSensitive)) {
if (index > 0 && !effectivePath.regionMatches(0, project.name, 0, index, !SystemInfo.isFileSystemCaseSensitive)) {
val moduleName = effectivePath.substring(0, index)
val token = ReadAction.start()
val module: Module?
try {
module = ModuleManager.getInstance(project).findModuleByName(moduleName)
}
finally {
token.finish()
}
val module = runReadAction { ModuleManager.getInstance(project).findModuleByName(moduleName) }
if (module != null && !module.isDisposed()) {
if (module != null && !module.isDisposed) {
effectivePath = effectivePath.substring(index + 1)
val resolver = WebServerPathToFileManager.getInstance(project).getResolver(effectivePath)
@@ -74,7 +65,7 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
}
}
val modules = runReadAction { ModuleManager.getInstance(project).getModules() }
val modules = runReadAction { ModuleManager.getInstance(project).modules }
val resolver = WebServerPathToFileManager.getInstance(project).getResolver(effectivePath)
for (rootProvider in RootProvider.values()) {
val result = findByRelativePath(project, effectivePath, modules, rootProvider, resolver)
@@ -85,63 +76,57 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
return findInLibraries(project, modules, effectivePath, resolver)
}
override fun getRoot(file: VirtualFile, project: Project): PathInfo? {
override fun getPathInfo(file: VirtualFile, project: Project): PathInfo? {
runReadAction {
val directoryIndex = DirectoryIndex.getInstance(project)
val info = directoryIndex.getInfoForFile(file)
// we serve excluded files
if (!info.isExcluded() && !info.isInProject()) {
if (!info.isExcluded && !info.isInProject) {
// javadoc jars is "not under project", but actually is, so, let's check project library table
return if (file.getFileSystem() === JarFileSystem.getInstance()) getInfoForDocJar(file, project) else null
return if (file.fileSystem == JarFileSystem.getInstance()) getInfoForDocJar(file, project) else null
}
var root = info.getSourceRoot()
var root = info.sourceRoot
val isLibrary: Boolean
if (root == null) {
root = info.getContentRoot()
root = info.contentRoot
if (root == null) {
root = info.getLibraryClassRoot()
root = info.libraryClassRoot
isLibrary = true
assert(root != null) { file.getPresentableUrl() }
assert(root != null) { file.presentableUrl }
}
else {
isLibrary = false
}
}
else {
isLibrary = info.isInLibrarySource()
isLibrary = info.isInLibrarySource
}
var module = info.getModule()
var module = info.module
if (isLibrary && module == null) {
for (entry in directoryIndex.getOrderEntries(info)) {
if (entry is ModuleLibraryOrderEntryImpl) {
module = entry.getOwnerModule()
module = entry.ownerModule
break
}
}
}
return PathInfo(file, root!!, getModuleNameQualifier(project, module), isLibrary)
return PathInfo(null, file, root!!, getModuleNameQualifier(project, module), isLibrary)
}
}
private enum class RootProvider {
SOURCE {
override fun getRoots(rootManager: ModuleRootManager): Array<VirtualFile> {
return rootManager.getSourceRoots()
}
override fun getRoots(rootManager: ModuleRootManager) = rootManager.sourceRoots
},
CONTENT {
override fun getRoots(rootManager: ModuleRootManager): Array<VirtualFile> {
return rootManager.getContentRoots()
}
override fun getRoots(rootManager: ModuleRootManager) = rootManager.contentRoots
},
EXCLUDED {
override fun getRoots(rootManager: ModuleRootManager): Array<VirtualFile> {
return rootManager.getExcludeRoots()
}
override fun getRoots(rootManager: ModuleRootManager) = rootManager.excludeRoots
};
public abstract fun getRoots(rootManager: ModuleRootManager): Array<VirtualFile>
@@ -167,7 +152,7 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
}
}
private fun findInModuleLibraries(path: String, module: Module, resolver: PairFunction<String, VirtualFile, VirtualFile>): PathInfo? {
private fun findInModuleLibraries(path: String, module: Module, resolver: FileResolver): PathInfo? {
val index = path.indexOf('/')
if (index <= 0) {
return null
@@ -178,7 +163,7 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
return result.get()
}
private fun findInLibraries(project: Project, modules: Array<Module>, path: String, resolver: PairFunction<String, VirtualFile, VirtualFile>): PathInfo? {
private fun findInLibraries(project: Project, modules: Array<Module>, path: String, resolver: FileResolver): PathInfo? {
val index = path.indexOf('/')
if (index < 0) {
return null
@@ -189,14 +174,14 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
runReadAction {
val result = Ref.create<PathInfo>()
for (module in modules) {
if (!module.isDisposed()) {
if (!module.isDisposed) {
if (findInModuleLibraries(resolver, libraryFileName, relativePath, result, module)) {
return result.get()
}
}
}
for (library in LibraryTablesRegistrar.getInstance().getLibraryTable(project).getLibraries()) {
for (library in LibraryTablesRegistrar.getInstance().getLibraryTable(project).libraries) {
val pathInfo = findInLibrary(libraryFileName, relativePath, library, resolver)
if (pathInfo != null) {
return pathInfo
@@ -207,24 +192,22 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
return null
}
private fun findInModuleLibraries(resolver: PairFunction<String, VirtualFile, VirtualFile>, libraryFileName: String, relativePath: String, result: Ref<PathInfo>, module: Module): Boolean {
private fun findInModuleLibraries(resolver: FileResolver, libraryFileName: String, relativePath: String, result: Ref<PathInfo>, module: Module): Boolean {
ModuleRootManager.getInstance(module).orderEntries().forEachLibrary(object : Processor<Library> {
override fun process(library: Library): Boolean {
result.set(findInLibrary(libraryFileName, relativePath, library, resolver))
return result.isNull()
return result.isNull
}
})
return !result.isNull()
return !result.isNull
}
private fun findInLibrary(libraryFileName: String, relativePath: String, library: Library, resolver: PairFunction<String, VirtualFile, VirtualFile>): PathInfo? {
for (rootType in ORDER_ROOT_TYPES.getValue()) {
private fun findInLibrary(libraryFileName: String, relativePath: String, library: Library, resolver: FileResolver): PathInfo? {
for (rootType in ORDER_ROOT_TYPES.value) {
for (root in library.getFiles(rootType)) {
if (StringUtil.equalsIgnoreCase(root.getNameSequence(), libraryFileName)) {
val file = resolver.`fun`(relativePath, root)
if (file != null) {
return PathInfo(file, root, null, true)
}
if (StringUtil.equalsIgnoreCase(root.nameSequence, libraryFileName)) {
val result = resolver.resolve(relativePath, root, isLibrary = true) ?: continue
return result
}
}
}
@@ -241,7 +224,7 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
override fun process(library: Library): Boolean {
for (root in library.getFiles(javaDocRootType)) {
if (VfsUtilCore.isAncestor(root, file, false)) {
result = PathInfo(file, root, getModuleNameQualifier(project, module), true)
result = PathInfo(null, file, root, getModuleNameQualifier(project, module), true)
return false
}
}
@@ -252,8 +235,8 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
val processor = LibraryProcessor()
runReadAction {
val moduleManager = ModuleManager.getInstance(project)
for (module in moduleManager.getModules()) {
if (module.isDisposed()) {
for (module in moduleManager.modules) {
if (module.isDisposed) {
continue
}
@@ -265,7 +248,7 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
}
processor.module = null
for (library in LibraryTablesRegistrar.getInstance().getLibraryTable(project).getLibraries()) {
for (library in LibraryTablesRegistrar.getInstance().getLibraryTable(project).libraries) {
if (!processor.process(library)) {
return processor.result
}
@@ -276,25 +259,23 @@ class DefaultWebServerRootsProvider : WebServerRootsProvider() {
}
private fun getModuleNameQualifier(project: Project, module: Module?): String? {
if (module != null && PlatformUtils.isIntelliJ() && !(module.getName().equals(project.getName(), ignoreCase = true) || compareNameAndProjectBasePath(module.getName(), project))) {
return module.getName()
if (module != null && PlatformUtils.isIntelliJ() && !(module.name.equals(project.name, ignoreCase = true) || compareNameAndProjectBasePath(module.name, project))) {
return module.name
}
return null
}
private fun findByRelativePath(path: String, roots: Array<VirtualFile>, resolver: PairFunction<String, VirtualFile, VirtualFile>, moduleName: String?): PathInfo? {
private fun findByRelativePath(path: String, roots: Array<VirtualFile>, resolver: FileResolver, moduleName: String?): PathInfo? {
for (root in roots) {
val file = resolver.`fun`(path, root)
if (file != null) {
return PathInfo(file, root, moduleName, false)
}
val result = resolver.resolve(path, root, moduleName) ?: continue
return result
}
return null
}
private fun findByRelativePath(project: Project, path: String, modules: Array<Module>, rootProvider: RootProvider, resolver: PairFunction<String, VirtualFile, VirtualFile>): PathInfo? {
private fun findByRelativePath(project: Project, path: String, modules: Array<Module>, rootProvider: RootProvider, resolver: FileResolver): PathInfo? {
for (module in modules) {
if (!module.isDisposed()) {
if (!module.isDisposed) {
val moduleRootManager = ModuleRootManager.getInstance(module)
val result = findByRelativePath(path, rootProvider.getRoots(moduleRootManager), resolver, null)
if (result != null) {
@@ -1,18 +0,0 @@
package org.jetbrains.builtInWebServer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PairFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class PrefixlessWebServerRootsProvider extends WebServerRootsProvider {
@Nullable
@Override
public final PathInfo resolve(@NotNull String path, @NotNull Project project) {
return resolve(path, project, WebServerPathToFileManager.getInstance(project).getResolver(path));
}
@Nullable
public abstract PathInfo resolve(@NotNull String path, @NotNull Project project, @NotNull PairFunction<String, VirtualFile, VirtualFile> resolver);
}
@@ -0,0 +1,9 @@
package org.jetbrains.builtInWebServer
import com.intellij.openapi.project.Project
abstract class PrefixlessWebServerRootsProvider : WebServerRootsProvider() {
override final fun resolve(path: String, project: Project) = resolve(path, project, WebServerPathToFileManager.getInstance(project).getResolver(path))
abstract fun resolve(path: String, project: Project, resolver: FileResolver): PathInfo?
}
@@ -0,0 +1,105 @@
package org.jetbrains.builtInWebServer
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtilRt
import com.intellij.util.PathUtilRt
import io.netty.buffer.ByteBufUtf8Writer
import io.netty.channel.Channel
import io.netty.channel.ChannelFutureListener
import io.netty.handler.codec.http.*
import io.netty.handler.stream.ChunkedStream
import org.jetbrains.builtInWebServer.ssi.SsiExternalResolver
import org.jetbrains.builtInWebServer.ssi.SsiProcessor
import org.jetbrains.io.FileResponses
import org.jetbrains.io.Responses
import java.io.File
private class StaticFileHandler : WebServerFileHandler() {
private var ssiProcessor: SsiProcessor? = null
override fun process(pathInfo: PathInfo, canonicalRequestPath: CharSequence, project: Project, request: FullHttpRequest, channel: Channel, isCustomHost: Boolean): Boolean {
if (pathInfo.ioFile != null || pathInfo.file!!.isInLocalFileSystem) {
val ioFile = pathInfo.ioFile ?: File(pathInfo.file!!.path)
val nameSequence = pathInfo.name
//noinspection SpellCheckingInspection
if (StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtml") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".stm") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtm")) {
processSsi(ioFile, canonicalRequestPath, project, request, channel, isCustomHost)
return true
}
if (hasAccess(ioFile)) {
FileResponses.sendFile(request, channel, ioFile)
}
else {
Responses.sendStatus(HttpResponseStatus.FORBIDDEN, channel, request)
}
}
else {
val file = pathInfo.file!!
val response = FileResponses.prepareSend(request, channel, file.timeStamp, file.path) ?: return true
val keepAlive = Responses.addKeepAliveIfNeed(response, request)
if (request.method() != HttpMethod.HEAD) {
HttpUtil.setContentLength(response, file.length)
}
channel.write(response)
if (request.method() != HttpMethod.HEAD) {
channel.write(ChunkedStream(file.inputStream))
}
val future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
if (!keepAlive) {
future.addListener(ChannelFutureListener.CLOSE)
}
}
return true
}
private fun processSsi(file: File, canonicalRequestPath: CharSequence, project: Project, request: FullHttpRequest, channel: Channel, isCustomHost: Boolean) {
var path = PathUtilRt.getParentPath(canonicalRequestPath.toString())
if (!isCustomHost) {
// remove project name - SSI resolves files only inside current project
path = path.substring(path.indexOf('/', 1) + 1)
}
if (ssiProcessor == null) {
ssiProcessor = SsiProcessor(false)
}
val buffer = channel.alloc().ioBuffer()
val keepAlive: Boolean
var releaseBuffer = true
try {
val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.parentFile), FileUtil.loadFile(file), file.lastModified(), ByteBufUtf8Writer(buffer))
val response = FileResponses.prepareSend(request, channel, lastModified, file.path) ?: return
keepAlive = Responses.addKeepAliveIfNeed(response, request)
if (request.method() != HttpMethod.HEAD) {
HttpUtil.setContentLength(response, buffer.readableBytes().toLong())
}
channel.write(response)
if (request.method() != HttpMethod.HEAD) {
releaseBuffer = false
channel.write(buffer)
}
}
finally {
if (releaseBuffer) {
buffer.release()
}
}
val future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
if (!keepAlive) {
future.addListener(ChannelFutureListener.CLOSE)
}
}
// deny access to .htaccess files
private fun hasAccess(result: File) = !result.isDirectory && result.canRead() && !(result.isHidden || result.name.startsWith(".ht"))
}
@@ -17,7 +17,6 @@ package org.jetbrains.builtInWebServer;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
import org.jetbrains.annotations.NotNull;
@@ -27,7 +26,7 @@ import java.io.IOException;
public abstract class WebServerFileHandler {
static final ExtensionPointName<WebServerFileHandler> EP_NAME = ExtensionPointName.create("org.jetbrains.webServerFileHandler");
public abstract boolean process(@NotNull VirtualFile file,
public abstract boolean process(@NotNull PathInfo pathInfo,
@NotNull CharSequence canonicalRequestPath,
@NotNull Project project,
@NotNull FullHttpRequest request,
@@ -1,142 +0,0 @@
package org.jetbrains.builtInWebServer;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.intellij.ProjectTopics;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.PairFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Implement {@link WebServerRootsProvider} to add your provider
*/
public class WebServerPathToFileManager {
private static final PairFunction<String, VirtualFile, VirtualFile> RELATIVE_PATH_RESOLVER = new PairFunction<String, VirtualFile, VirtualFile>() {
@Nullable
@Override
public VirtualFile fun(String path, VirtualFile parent) {
return parent.findFileByRelativePath(path);
}
};
private static final PairFunction<String, VirtualFile, VirtualFile> EMPTY_PATH_RESOLVER = new PairFunction<String, VirtualFile, VirtualFile>() {
@Nullable
@Override
public VirtualFile fun(String path, VirtualFile parent) {
return BuiltInWebServerPackage.findIndexFile(parent);
}
};
private final Project project;
final Cache<String, VirtualFile> pathToFileCache = CacheBuilder.newBuilder().maximumSize(512).expireAfterAccess(10, TimeUnit.MINUTES).build();
// time to expire should be greater than pathToFileCache
private final Cache<VirtualFile, PathInfo> fileToRoot = CacheBuilder.newBuilder().maximumSize(512).expireAfterAccess(11, TimeUnit.MINUTES).build();
public static WebServerPathToFileManager getInstance(@NotNull Project project) {
return ServiceManager.getService(project, WebServerPathToFileManager.class);
}
public WebServerPathToFileManager(@NotNull Application application, @NotNull Project project) {
this.project = project;
application.getMessageBus().connect(project).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
if (event instanceof VFileContentChangeEvent) {
VirtualFile file = ((VFileContentChangeEvent)event).getFile();
for (WebServerRootsProvider rootsProvider : WebServerRootsProvider.EP_NAME.getExtensions()) {
if (rootsProvider.isClearCacheOnFileContentChanged(file)) {
clearCache();
break;
}
}
}
else {
clearCache();
break;
}
}
}
});
project.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
@Override
public void rootsChanged(ModuleRootEvent event) {
clearCache();
}
});
}
private void clearCache() {
pathToFileCache.invalidateAll();
fileToRoot.invalidateAll();
}
@Nullable
public VirtualFile get(@NotNull String path) {
return get(path, true);
}
@Nullable
public VirtualFile get(@NotNull String path, boolean cacheResult) {
VirtualFile result = pathToFileCache.getIfPresent(path);
if (result == null || !result.isValid()) {
result = findByRelativePath(project, path);
if (cacheResult && result != null && result.isValid()) {
pathToFileCache.put(path, result);
}
}
return result;
}
@Nullable
public String getPath(@NotNull VirtualFile file) {
PathInfo pathInfo = getRoot(file);
return pathInfo == null ? null : pathInfo.getPath();
}
@Nullable
public PathInfo getRoot(@NotNull VirtualFile child) {
PathInfo result = fileToRoot.getIfPresent(child);
if (result == null) {
for (WebServerRootsProvider rootsProvider : WebServerRootsProvider.EP_NAME.getExtensions()) {
result = rootsProvider.getRoot(child, project);
if (result != null) {
fileToRoot.put(child, result);
break;
}
}
}
return result;
}
@Nullable
VirtualFile findByRelativePath(@NotNull Project project, @NotNull String path) {
for (WebServerRootsProvider rootsProvider : WebServerRootsProvider.EP_NAME.getExtensions()) {
PathInfo result = rootsProvider.resolve(path, project);
if (result != null) {
fileToRoot.put(result.getChild(), result);
return result.getChild();
}
}
return null;
}
@NotNull
public PairFunction<String, VirtualFile, VirtualFile> getResolver(@NotNull String path) {
return path.isEmpty() ? EMPTY_PATH_RESOLVER : RELATIVE_PATH_RESOLVER;
}
}
@@ -0,0 +1,143 @@
package org.jetbrains.builtInWebServer
import com.google.common.cache.CacheBuilder
import com.intellij.ProjectTopics
import com.intellij.openapi.application.Application
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleRootAdapter
import com.intellij.openapi.roots.ModuleRootEvent
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.newvfs.BulkFileListener
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import java.io.File
import java.util.concurrent.TimeUnit
/**
* Implement [WebServerRootsProvider] to add your provider
*/
class WebServerPathToFileManager(application: Application, private val project: Project) {
val pathToInfoCache = CacheBuilder.newBuilder().maximumSize(512).expireAfterAccess(10, TimeUnit.MINUTES).build<String, PathInfo>()
// time to expire should be greater than pathToFileCache
private val virtualFileToPathInfo = CacheBuilder.newBuilder().maximumSize(512).expireAfterAccess(11, TimeUnit.MINUTES).build<VirtualFile, PathInfo>()
init {
application.messageBus.connect(project).subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
override fun after(events: List<VFileEvent>) {
for (event in events) {
if (event is VFileContentChangeEvent) {
val file = event.file
for (rootsProvider in WebServerRootsProvider.EP_NAME.extensions) {
if (rootsProvider.isClearCacheOnFileContentChanged(file)) {
clearCache()
break
}
}
}
else {
clearCache()
break
}
}
}
})
project.messageBus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, object : ModuleRootAdapter() {
override fun rootsChanged(event: ModuleRootEvent) {
clearCache()
}
})
}
private fun clearCache() {
pathToInfoCache.invalidateAll()
virtualFileToPathInfo.invalidateAll()
}
@JvmOverloads fun findVirtualFile(path: String, cacheResult: Boolean = true): VirtualFile? {
val pathInfo = getPathInfo(path, cacheResult) ?: return null
return pathInfo.file ?: return LocalFileSystem.getInstance().findFileByIoFile(pathInfo.ioFile!!)
}
fun getPathInfo(path: String, cacheResult: Boolean = true): PathInfo? {
var pathInfo = pathToInfoCache.getIfPresent(path)
if (pathInfo == null || !pathInfo.isValid) {
pathInfo = doFindByRelativePath(path)
if (cacheResult && pathInfo != null && pathInfo.isValid) {
pathToInfoCache.put(path, pathInfo)
}
}
return pathInfo
}
fun getPath(file: VirtualFile) = getPathInfo(file)?.path
private fun getPathInfo(child: VirtualFile): PathInfo? {
var result = virtualFileToPathInfo.getIfPresent(child)
if (result == null) {
for (infoProvider in WebServerRootsProvider.EP_NAME.extensions) {
result = infoProvider.getPathInfo(child, project)
if (result != null) {
virtualFileToPathInfo.put(child, result)
break
}
}
}
return result
}
internal fun doFindByRelativePath(path: String): PathInfo? {
for (rootsProvider in WebServerRootsProvider.EP_NAME.extensions) {
val result = rootsProvider.resolve(path, project)
if (result != null) {
if (result.file != null) {
virtualFileToPathInfo.put(result.file, result)
}
return result
}
}
return null
}
fun getResolver(path: String) = if (path.isEmpty()) EMPTY_PATH_RESOLVER else RELATIVE_PATH_RESOLVER
companion object {
private val RELATIVE_PATH_RESOLVER = object : FileResolver {
override fun resolve(path: String, root: VirtualFile, moduleName: String?, isLibrary: Boolean): PathInfo? {
// WEB-17691 built-in server doesn't serve files it doesn't have in the project tree
// temp:// reports isInLocalFileSystem == true, but it is not true
if (root.isInLocalFileSystem && root.fileSystem == LocalFileSystem.getInstance()) {
val file = File(root.path, path)
if (file.exists()) {
return PathInfo(file, null, root, moduleName, isLibrary)
}
else {
return null
}
}
else {
val file = root.findFileByRelativePath(path) ?: return null
return PathInfo(null, file, root, moduleName, isLibrary)
}
}
}
private val EMPTY_PATH_RESOLVER = object : FileResolver {
override fun resolve(path: String, root: VirtualFile, moduleName: String?, isLibrary: Boolean): PathInfo? {
val file = findIndexFile(root) ?: return null
return PathInfo(null, file, root, moduleName, isLibrary)
}
}
@JvmStatic fun getInstance(project: Project): WebServerPathToFileManager {
return ServiceManager.getService(project, WebServerPathToFileManager::class.java)
}
}
}
interface FileResolver {
fun resolve(path: String, root: VirtualFile, moduleName: String? = null, isLibrary: Boolean = false): PathInfo?
}
@@ -17,13 +17,14 @@ package org.jetbrains.builtInWebServer.ssi;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import gnu.trove.THashMap;
import io.netty.handler.codec.http.HttpRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.builtInWebServer.PathInfo;
import org.jetbrains.builtInWebServer.WebServerPathToFileManager;
import java.io.File;
import java.util.Collection;
import java.util.Map;
@@ -44,12 +45,12 @@ public final class SsiExternalResolver {
private Map<String, String> variables = new THashMap<String, String>();
private final String parentPath;
@NotNull private final VirtualFile parentFile;
@NotNull private final File parentFile;
public SsiExternalResolver(@NotNull Project project,
@NotNull HttpRequest request,
@NotNull String parentPath,
@NotNull VirtualFile parentFile) {
@NotNull File parentFile) {
this.project = project;
this.request = request;
this.parentPath = parentPath;
@@ -75,23 +76,30 @@ public final class SsiExternalResolver {
}
@Nullable
public VirtualFile findFile(@NotNull String originalPath, boolean virtual) {
public File findFile(@NotNull String originalPath, boolean virtual) {
String path = FileUtil.toCanonicalPath(originalPath, '/');
if (!virtual) {
return parentFile.findFileByRelativePath(path);
return new File(parentFile, path);
}
path = path.charAt(0) == '/' ? path : (parentPath + '/' + path);
return WebServerPathToFileManager.getInstance(project).get(path);
PathInfo pathInfo = WebServerPathToFileManager.getInstance(project).getPathInfo(path, true);
if (pathInfo == null) {
return null;
}
if (pathInfo.getIoFile() != null) {
return pathInfo.getIoFile();
}
return new File(pathInfo.getFile().getPath());
}
public long getFileLastModified(String path, boolean virtual) {
VirtualFile file = findFile(path, virtual);
return file == null ? 0 : file.getTimeStamp();
File file = findFile(path, virtual);
return file == null || !file.exists() ? 0 : file.lastModified();
}
public long getFileSize(@NotNull String path, boolean virtual) {
VirtualFile file = findFile(path, virtual);
return file == null ? -1 : file.getLength();
File file = findFile(path, virtual);
return file == null || !file.exists() ? -1 : file.length();
}
}
@@ -16,12 +16,13 @@
package org.jetbrains.builtInWebServer.ssi;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import gnu.trove.THashMap;
import io.netty.buffer.ByteBufUtf8Writer;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
@@ -109,15 +110,15 @@ public class SsiProcessor {
try {
boolean virtual = paramName.equalsIgnoreCase("virtual");
lastModified = state.ssiExternalResolver.getFileLastModified(substitutedValue, virtual);
VirtualFile file = state.ssiExternalResolver.findFile(substitutedValue, virtual);
File file = state.ssiExternalResolver.findFile(substitutedValue, virtual);
if (file == null) {
LOG.warn("#include-- Couldn't find file: " + substitutedValue);
return 0;
}
InputStream in = file.getInputStream();
InputStream in = new FileInputStream(file);
try {
writer.write(in, (int)file.getLength());
writer.write(in, (int)file.length());
}
finally {
in.close();
@@ -218,7 +218,7 @@ class OpenFileHttpService extends RestService {
}
if (virtualFile == null) {
virtualFile = WebServerPathToFileManager.getInstance(openedProject).get(path);
virtualFile = WebServerPathToFileManager.getInstance(openedProject).findVirtualFile(path);
}
if (virtualFile != null) {
project = openedProject;
@@ -1,7 +1,5 @@
package org.jetbrains.io.fastCgi
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import io.netty.buffer.ByteBuf
import io.netty.buffer.ByteBufAllocator
import io.netty.buffer.ByteBufUtil
@@ -9,7 +7,7 @@ import io.netty.buffer.ByteBufUtilEx
import io.netty.channel.Channel
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.HttpHeaderNames
import org.jetbrains.builtInWebServer.WebServerPathToFileManager
import org.jetbrains.builtInWebServer.PathInfo
import org.jetbrains.io.Responses
import java.net.InetSocketAddress
import java.util.*
@@ -34,11 +32,10 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) {
buffer!!.writeZero(5)
}
public fun writeFileHeaders(file: VirtualFile, project: Project, canonicalRequestPath: CharSequence) {
val root = WebServerPathToFileManager.getInstance(project).getRoot(file)
LOG.assertTrue(root != null)
addHeader("DOCUMENT_ROOT", root!!.root.path)
addHeader("SCRIPT_FILENAME", file.path)
public fun writeFileHeaders(pathInfo: PathInfo, canonicalRequestPath: CharSequence) {
val root = pathInfo.root
addHeader("DOCUMENT_ROOT", root.path)
addHeader("SCRIPT_FILENAME", pathInfo.path)
addHeader("SCRIPT_NAME", canonicalRequestPath)
}
+29 -29
View File
@@ -25,29 +25,29 @@ class RestApiTest {
private val manager = TestManager(projectRule, tempDirManager)
private val ruleChain = RuleChain(tempDirManager, manager)
public Rule fun getChain(): RuleChain = ruleChain
@Rule fun getChain() = ruleChain
Test(timeout = 60000)
TestDescriptor(filePath = "", status = 400)
public fun fileEmptyRequest() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "", status = 400)
fun fileEmptyRequest() {
doTest()
}
Test(timeout = 60000)
TestDescriptor(filePath = "foo.txt", relativeToProject = true, status = 200)
public fun relativeToProject() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "foo.txt", relativeToProject = true, status = 200)
fun relativeToProject() {
doTest()
}
Test(timeout = 60000)
TestDescriptor(filePath = "foo.txt", relativeToProject = true, line = 1, status = 200)
public fun relativeToProjectWithLine() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "foo.txt", relativeToProject = true, line = 1, status = 200)
fun relativeToProjectWithLine() {
doTest()
}
Test(timeout = 60000)
TestDescriptor(filePath = "foo.txt", relativeToProject = true, line = 1, column = 13, status = 200)
public fun relativeToProjectWithLineAndColumn() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "foo.txt", relativeToProject = true, line = 1, column = 13, status = 200)
fun relativeToProjectWithLineAndColumn() {
doTest()
}
@@ -57,26 +57,26 @@ class RestApiTest {
doTest()
}
Test(timeout = 60000)
TestDescriptor(filePath = "bar/42/foo.txt", doNotCreate = true, status = 404)
public fun relativeNonExistent() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "bar/42/foo.txt", doNotCreate = true, status = 404)
fun relativeNonExistent() {
doTest()
}
Test(timeout = 60000)
TestDescriptor(filePath = "_tmp_", doNotCreate = true, status = 404)
public fun absoluteNonExistent() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "_tmp_", doNotCreate = true, status = 404)
fun absoluteNonExistent() {
doTest()
}
Test(timeout = 60000)
TestDescriptor(filePath = "_tmp_", status = 200)
public fun absolute() {
@Test(timeout = 60000)
@TestDescriptor(filePath = "_tmp_", status = 200)
fun absolute() {
doTest()
}
private fun doTest() {
val serviceUrl = "http://localhost:" + BuiltInServerManager.getInstance().getPort() + "/api/file"
val serviceUrl = "http://localhost:${BuiltInServerManager.getInstance().port}/api/file"
var url = serviceUrl + (if (manager.filePath == null) "" else ("/${manager.filePath}"))
val line = manager.annotation?.line ?: -1
if (line != -1) {
@@ -89,21 +89,21 @@ class RestApiTest {
var connection = URL(url).openConnection() as HttpURLConnection
val expectedStatus = HttpResponseStatus.valueOf(manager.annotation?.status ?: 200)
assertThat(HttpResponseStatus.valueOf(connection.getResponseCode())).isEqualTo(expectedStatus)
assertThat(HttpResponseStatus.valueOf(connection.responseCode)).isEqualTo(expectedStatus)
connection = URL("$serviceUrl?file=${manager.filePath ?: ""}&line=$line&column=$column").openConnection() as HttpURLConnection
assertThat(HttpResponseStatus.valueOf(connection.getResponseCode())).isEqualTo(expectedStatus)
assertThat(HttpResponseStatus.valueOf(connection.responseCode)).isEqualTo(expectedStatus)
connection = URL("$serviceUrl").openConnection() as HttpURLConnection
connection.setRequestMethod("POST")
connection.setDoOutput(true)
val writer = JsonWriter(OutputStreamWriter(BufferedOutputStream(connection.getOutputStream()), CharsetToolkit.UTF8_CHARSET))
connection.requestMethod = "POST"
connection.doOutput = true
val writer = JsonWriter(OutputStreamWriter(BufferedOutputStream(connection.outputStream), CharsetToolkit.UTF8_CHARSET))
writer.beginObject()
writer.name("file").value(manager.filePath)
writer.name("line").value(line)
writer.name("column").value(column)
writer.endObject()
writer.close()
assertThat(HttpResponseStatus.valueOf(connection.getResponseCode())).isEqualTo(expectedStatus)
assertThat(HttpResponseStatus.valueOf(connection.responseCode)).isEqualTo(expectedStatus)
}
}
@@ -79,6 +79,7 @@ abstract class ComponentStoreImpl : IComponentStore {
settingsSavingComponents.add(component)
}
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
if (!(component is JDOMExternalizable || component is PersistentStateComponent<*>)) {
return
}
@@ -88,10 +89,11 @@ abstract class ComponentStoreImpl : IComponentStore {
componentNameIfStateExists = if (component is PersistentStateComponent<*>) {
val stateSpec = StoreUtil.getStateSpec(component)
doAddComponent(stateSpec.name, component)
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
initPersistentComponent(stateSpec, component as PersistentStateComponent<Any>, null, false)
}
else {
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
initJdomExternalizable(component as JDOMExternalizable)
}
}
@@ -142,7 +144,7 @@ abstract class ComponentStoreImpl : IComponentStore {
CompoundRuntimeException.throwIfNotEmpty(errors)
}
override TestOnly fun saveApplicationComponent(component: Any) {
override @TestOnly fun saveApplicationComponent(component: Any) {
val externalizationSession = storageManager.startExternalization() ?: return
commitComponent(externalizationSession, component, null)
@@ -179,6 +181,7 @@ abstract class ComponentStoreImpl : IComponentStore {
}
private fun commitComponent(session: ExternalizationSession, component: Any, componentName: String?) {
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
if (component is PersistentStateComponent<*>) {
val state = component.getState()
if (state != null) {
@@ -199,7 +202,7 @@ abstract class ComponentStoreImpl : IComponentStore {
return errors
}
private fun initJdomExternalizable(component: JDOMExternalizable): String? {
private fun initJdomExternalizable(@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") component: JDOMExternalizable): String? {
val componentName = ComponentManagerImpl.getComponentName(component)
doAddComponent(componentName, component)
@@ -374,7 +377,7 @@ abstract class ComponentStoreImpl : IComponentStore {
override final fun reloadState(componentClass: Class<out PersistentStateComponent<*>>) {
val stateSpec = StoreUtil.getStateSpecOrError(componentClass)
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
val component = components.get(stateSpec.name) as PersistentStateComponent<Any>?
if (component != null) {
initPersistentComponent(stateSpec, component, emptySet(), true)
@@ -382,7 +385,7 @@ abstract class ComponentStoreImpl : IComponentStore {
}
private fun reloadState(componentName: String, changedStorages: Set<StateStorage>): Boolean {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
val component = components.get(componentName) as PersistentStateComponent<Any>?
if (component == null) {
return false
@@ -49,11 +49,9 @@ import gnu.trove.TObjectProcedure
import org.jdom.Document
import org.jdom.Element
import java.io.File
import java.io.FilenameFilter
import java.io.IOException
import java.io.InputStream
import java.util.ArrayList
import java.util.Collections
import java.util.*
public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val fileSpec: String,
private val processor: SchemeProcessor<E>,
@@ -80,8 +78,8 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
init {
if (processor is SchemeExtensionProvider) {
schemeExtension = processor.getSchemeExtension()
updateExtension = processor.isUpgradeNeeded()
schemeExtension = processor.schemeExtension
updateExtension = processor.isUpgradeNeeded
}
else {
schemeExtension = FileStorageCoreUtil.DEFAULT_EXT
@@ -103,33 +101,33 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
val directory = LocalFileSystem.getInstance().findFileByIoFile(ioDirectory) ?: return
this.directory = directory
directory.getChildren()
directory.children
if (directory is NewVirtualFile) {
directory.markDirty()
}
directory.refresh(true, false, Runnable {
directory.refresh(true, false, {
addVfsListener(virtualFileTrackerDisposable)
})
}
private fun addVfsListener(virtualFileTrackerDisposable: Disposable?) {
service<VirtualFileTracker>().addTracker("${LocalFileSystem.PROTOCOL_PREFIX}${ioDirectory.getAbsolutePath().replace(File.separatorChar, '/')}", object : VirtualFileAdapter() {
service<VirtualFileTracker>().addTracker("${LocalFileSystem.PROTOCOL_PREFIX}${ioDirectory.absolutePath.replace(File.separatorChar, '/')}", object : VirtualFileAdapter() {
override fun contentsChanged(event: VirtualFileEvent) {
if (event.getRequestor() != null || !isMy(event)) {
if (event.requestor != null || !isMy(event)) {
return
}
val oldScheme = findExternalizableSchemeByFileName(event.getFile().getName())
val oldScheme = findExternalizableSchemeByFileName(event.file.name)
var oldCurrentScheme: T? = null
if (oldScheme != null) {
oldCurrentScheme = currentScheme
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
removeScheme(oldScheme as T)
processor.onSchemeDeleted(oldScheme)
}
val newScheme = readSchemeFromFile(event.getFile(), false)
val newScheme = readSchemeFromFile(event.file, false)
if (newScheme != null) {
processor.initScheme(newScheme)
processor.onSchemeAdded(newScheme)
@@ -140,20 +138,20 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun updateCurrentScheme(oldCurrentScheme: T?, newCurrentScheme: E? = null) {
if (oldCurrentScheme != currentScheme && currentScheme == null) {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
setCurrent(newCurrentScheme as T? ?: schemes.firstOrNull())
}
}
override fun fileCreated(event: VirtualFileEvent) {
if (event.getRequestor() != null) {
if (event.requestor != null) {
return
}
if (event.getFile().isDirectory()) {
if (event.file.isDirectory) {
val dir = getDirectory()
if (event.getFile() == dir) {
for (file in dir!!.getChildren()) {
if (event.file == dir) {
for (file in dir.children) {
if (isMy(file)) {
schemeCreatedExternally(file)
}
@@ -161,7 +159,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
}
else if (isMy(event)) {
schemeCreatedExternally(event.getFile())
schemeCreatedExternally(event.file)
}
}
@@ -174,21 +172,21 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
override fun fileDeleted(event: VirtualFileEvent) {
if (event.getRequestor() != null) {
if (event.requestor != null) {
return
}
var oldCurrentScheme = currentScheme
if (event.getFile().isDirectory()) {
if (event.file.isDirectory) {
val dir = directory
if (event.getFile() == dir) {
if (event.file == dir) {
directory = null
removeExternalizableSchemes()
}
}
else if (isMy(event)) {
val scheme = findExternalizableSchemeByFileName(event.getFile().getName()) ?: return
@suppress("UNCHECKED_CAST")
val scheme = findExternalizableSchemeByFileName(event.file.name) ?: return
@Suppress("UNCHECKED_CAST")
removeScheme(scheme as T)
processor.onSchemeDeleted(scheme)
}
@@ -201,7 +199,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
override fun loadBundledScheme(resourceName: String, requestor: Any, convertor: ThrowableConvertor<Element, T, Throwable>) {
try {
val url = if (requestor is AbstractExtensionPointBean)
requestor.getLoaderForClass().getResource(resourceName)
requestor.loaderForClass.getResource(resourceName)
else
DecodeDefaultsUtil.getDefaults(requestor, resourceName)
if (url == null) {
@@ -212,17 +210,17 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
val element = JDOMUtil.load(URLUtil.openStream(url))
val scheme = convertor.convert(element)
if (scheme is ExternalizableScheme) {
val fileName = PathUtilRt.getFileName(url.getPath())
val fileName = PathUtilRt.getFileName(url.path)
val extension = getFileExtension(fileName, true)
val info = ExternalInfo(fileName.substring(0, fileName.length() - extension.length()), extension)
info.hash = JDOMUtil.getTreeHash(element, true)
info.schemeName = scheme.getName()
@suppress("UNCHECKED_CAST")
info.schemeName = scheme.name
@Suppress("UNCHECKED_CAST")
val oldInfo = schemeToInfo.put(scheme as E, info)
LOG.assertTrue(oldInfo == null)
val oldScheme = readOnlyExternalizableSchemes.put(scheme.getName(), scheme)
val oldScheme = readOnlyExternalizableSchemes.put(scheme.name, scheme)
if (oldScheme != null) {
LOG.warn("Duplicated scheme ${scheme.getName()} - old: $oldScheme, new $scheme")
LOG.warn("Duplicated scheme ${scheme.name} - old: $oldScheme, new $scheme")
}
}
@@ -248,9 +246,9 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
}
private fun isMy(event: VirtualFileEvent) = isMy(event.getFile())
private fun isMy(event: VirtualFileEvent) = isMy(event.file)
private fun isMy(file: VirtualFile) = StringUtilRt.endsWithIgnoreCase(file.getNameSequence(), schemeExtension)
private fun isMy(file: VirtualFile) = StringUtilRt.endsWithIgnoreCase(file.nameSequence, schemeExtension)
override fun loadSchemes(): Collection<E> {
val newSchemesOffset = schemes.size()
@@ -264,17 +262,17 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
}
else {
ioDirectory.listFiles(FilenameFilter({ parent, name -> canRead(name) }))?.let {
ioDirectory.listFiles({ parent, name -> canRead(name) })?.let {
for (file in it) {
if (file.isDirectory()) {
if (file.isDirectory) {
continue
}
try {
loadScheme(file.getName(), file.inputStream(), true)
loadScheme(file.name, file.inputStream(), true)
}
catch (e: Throwable) {
LOG.error("Cannot read scheme ${file.getPath()}", e)
LOG.error("Cannot read scheme ${file.path}", e)
}
}
}
@@ -282,7 +280,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
val list = SmartList<E>()
for (i in newSchemesOffset..schemes.size() - 1) {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
val scheme = schemes[i] as E
processor.initScheme(scheme)
list.add(scheme)
@@ -301,7 +299,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
// todo check is bundled/read-only schemes correctly handled
for (i in schemes.indices.reversed()) {
val scheme = schemes.get(i)
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
if (scheme is ExternalizableScheme && getState(scheme as E) != BaseSchemeProcessor.State.NON_PERSISTENT) {
if (scheme == currentScheme) {
currentScheme = null
@@ -315,7 +313,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun findExternalizableSchemeByFileName(fileName: String): E? {
for (scheme in schemes) {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
if (scheme is ExternalizableScheme && fileName == "${scheme.fileName}$schemeExtension") {
return scheme as E
}
@@ -324,7 +322,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
private fun isOverwriteOnLoad(existingScheme: E): Boolean {
if (readOnlyExternalizableSchemes.get(existingScheme.getName()) === existingScheme) {
if (readOnlyExternalizableSchemes.get(existingScheme.name) === existingScheme) {
// so, bundled scheme is shadowed
return true
}
@@ -337,7 +335,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun loadScheme(fileName: CharSequence, input: InputStream, duringLoad: Boolean): E? {
try {
val element = JDOMUtil.load(input)
@suppress("DEPRECATED_SYMBOL_WITH_MESSAGE", "UNCHECKED_CAST")
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE", "UNCHECKED_CAST")
val scheme = (if (processor is BaseSchemeProcessor<*>) {
processor.readScheme(element, duringLoad) as E?
}
@@ -353,9 +351,9 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
return null
}
val existingScheme = findSchemeByName(scheme.getName())
val existingScheme = findSchemeByName(scheme.name)
if (existingScheme != null) {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
if (existingScheme is ExternalizableScheme && isOverwriteOnLoad(existingScheme as E)) {
removeScheme(existingScheme)
}
@@ -367,7 +365,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
else {
// We don't load scheme with duplicated name - if we generate unique name for it, it will be saved then with new name.
// It is not what all can expect. Such situation in most cases indicates error on previous level, so, we just warn about it.
LOG.warn("Scheme file \"$fileName\" is not loaded because defines duplicated name \"${scheme.getName()}\"")
LOG.warn("Scheme file \"$fileName\" is not loaded because defines duplicated name \"${scheme.name}\"")
}
return null
}
@@ -383,9 +381,9 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
info.setFileNameWithoutExtension(fileNameWithoutExtension, extension)
}
info.hash = JDOMUtil.getTreeHash(element, true)
info.schemeName = scheme.getName()
info.schemeName = scheme.name
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
if (duringLoad) {
schemes.add(scheme as T)
}
@@ -406,13 +404,13 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun canRead(name: CharSequence) = updateExtension && StringUtilRt.endsWithIgnoreCase(name, DEFAULT_EXT) || StringUtilRt.endsWithIgnoreCase(name, schemeExtension)
private fun readSchemeFromFile(file: VirtualFile, duringLoad: Boolean): E? {
val fileName = file.getNameSequence()
if (file.isDirectory() || !canRead(fileName)) {
val fileName = file.nameSequence
if (file.isDirectory || !canRead(fileName)) {
return null
}
try {
return loadScheme(fileName, file.getInputStream(), duringLoad)
return loadScheme(fileName, file.inputStream, duringLoad)
}
catch (e: Throwable) {
LOG.error("Cannot read scheme $fileName", e)
@@ -425,7 +423,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
val nameGenerator = UniqueNameGenerator()
val schemesToSave = SmartList<E>()
for (scheme in schemes) {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
if (scheme is ExternalizableScheme) {
val state = getState(scheme as E)
if (state == BaseSchemeProcessor.State.NON_PERSISTENT) {
@@ -454,7 +452,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
}
if (!filesToDelete.isEmpty()) {
if (!filesToDelete.isEmpty) {
deleteFiles(errors)
// remove empty directory only if some file was deleted - avoid check on each save
if (!hasSchemes && (provider == null || !provider.enabled)) {
@@ -466,14 +464,14 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun removeDirectoryIfEmpty(errors: MutableList<Throwable>) {
ioDirectory.listFiles()?.let {
for (file in it) {
if (!file.isHidden()) {
LOG.info("Directory ${ioDirectory.getName()} is not deleted: at least one file ${file.getName()} exists")
if (!file.isHidden) {
LOG.info("Directory ${ioDirectory.name} is not deleted: at least one file ${file.name} exists")
return
}
}
}
LOG.info("Remove schemes directory ${ioDirectory.getName()}")
LOG.info("Remove schemes directory ${ioDirectory.name}")
directory = null
var deleteUsingIo = !useVfs
@@ -504,7 +502,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
(processor as BaseSchemeProcessor<E>).getState(scheme)
}
else {
@suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
if (processor.shouldBeSaved(scheme)) BaseSchemeProcessor.State.POSSIBLY_CHANGED else BaseSchemeProcessor.State.NON_PERSISTENT
}
}
@@ -521,7 +519,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
var fileNameWithoutExtension = currentFileNameWithoutExtension
if (fileNameWithoutExtension == null || isRenamed(scheme)) {
fileNameWithoutExtension = nameGenerator.generateUniqueName(FileUtil.sanitizeFileName(scheme.getName(), false))
fileNameWithoutExtension = nameGenerator.generateUniqueName(FileUtil.sanitizeFileName(scheme.name, false))
}
val newHash = JDOMUtil.getTreeHash(element!!, true)
@@ -530,7 +528,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
// save only if scheme differs from bundled
val bundledScheme = readOnlyExternalizableSchemes.get(scheme.getName())
val bundledScheme = readOnlyExternalizableSchemes.get(scheme.name)
if (bundledScheme != null && schemeToInfo.get(bundledScheme)?.hash == newHash) {
externalInfo?.scheduleDelete()
return
@@ -560,7 +558,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
if (useVfs) {
var file: VirtualFile? = null
var dir = getDirectory()
if (dir == null || !dir.isValid()) {
if (dir == null || !dir.isValid) {
dir = createDir(ioDirectory, this)
directory = dir
}
@@ -588,14 +586,14 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
if (renamed) {
externalInfo!!.scheduleDelete()
}
FileUtil.writeToFile(File(ioDirectory, fileName), byteOut.getInternalBuffer(), 0, byteOut.size())
FileUtil.writeToFile(File(ioDirectory, fileName), byteOut.internalBuffer, 0, byteOut.size())
}
}
else {
if (renamed) {
externalInfo!!.scheduleDelete()
}
provider!!.write(providerPath, byteOut.getInternalBuffer(), byteOut.size(), roamingType)
provider!!.write(providerPath, byteOut.internalBuffer, byteOut.size(), roamingType)
}
if (externalInfo == null) {
@@ -606,7 +604,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
externalInfo.setFileNameWithoutExtension(fileNameWithoutExtension, schemeExtension)
}
externalInfo.hash = newHash
externalInfo.schemeName = scheme.getName()
externalInfo.schemeName = scheme.name
}
private fun ExternalInfo.scheduleDelete() {
@@ -615,7 +613,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun isRenamed(scheme: ExternalizableScheme): Boolean {
val info = schemeToInfo.get(scheme)
return info != null && scheme.getName() != info.schemeName
return info != null && scheme.name != info.schemeName
}
private fun deleteFiles(errors: MutableList<Throwable>) {
@@ -640,8 +638,8 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
if (!deleteUsingIo) {
var token: AccessToken? = null
try {
for (file in dir!!.getChildren()) {
if (filesToDelete.contains(file.getName())) {
for (file in dir!!.children) {
if (filesToDelete.contains(file.name)) {
if (token == null) {
token = WriteAction.start()
}
@@ -712,13 +710,13 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
private fun retainExternalInfo(newSchemes: List<T>) {
if (schemeToInfo.isEmpty()) {
if (schemeToInfo.isEmpty) {
return
}
schemeToInfo.retainEntries(object : TObjectObjectProcedure<E, ExternalInfo> {
override fun execute(scheme: E, info: ExternalInfo): Boolean {
if (readOnlyExternalizableSchemes.get(scheme.getName()) == scheme) {
if (readOnlyExternalizableSchemes.get(scheme.name) == scheme) {
return true
}
@@ -742,16 +740,16 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
var toReplace = -1
for (i in schemes.indices) {
val existing = schemes.get(i)
if (existing.getName() == scheme.getName()) {
if (existing.name == scheme.name) {
if (!Comparing.equal<Class<out Scheme>>(existing.javaClass, scheme.javaClass)) {
LOG.warn("'${scheme.getName()}' ${existing.javaClass.getSimpleName()} replaced with ${scheme.javaClass.getSimpleName()}")
LOG.warn("'${scheme.name}' ${existing.javaClass.simpleName} replaced with ${scheme.javaClass.simpleName}")
}
toReplace = i
if (replaceExisting && existing is ExternalizableScheme) {
val oldInfo = schemeToInfo.remove(existing)
if (oldInfo != null && scheme is ExternalizableScheme && !schemeToInfo.containsKey(scheme)) {
@suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST")
schemeToInfo.put(scheme as E, oldInfo)
}
}
@@ -765,7 +763,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
schemes.set(toReplace, scheme)
}
else {
scheme.renameScheme(UniqueNameGenerator.generateUniqueName(scheme.getName(), collectExistingNames(schemes)))
scheme.renameScheme(UniqueNameGenerator.generateUniqueName(scheme.name, collectExistingNames(schemes)))
schemes.add(scheme)
}
@@ -780,7 +778,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private fun collectExistingNames(schemes: Collection<T>): Collection<String> {
val result = THashSet<String>(schemes.size())
for (scheme in schemes) {
result.add(scheme.getName())
result.add(scheme.name)
}
return result
}
@@ -802,7 +800,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
override fun findSchemeByName(schemeName: String): T? {
for (scheme in schemes) {
if (scheme.getName() == schemeName) {
if (scheme.name == schemeName) {
return scheme
}
}
@@ -822,7 +820,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
override fun removeScheme(scheme: T) {
for (i in schemes.size() - 1 downTo 0) {
val s = schemes.get(i)
if (scheme.getName() == s.getName()) {
if (scheme.name == s.name) {
if (currentScheme == s) {
currentScheme = null
}
@@ -843,7 +841,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
val names = ArrayList<String>(schemes.size())
for (scheme in schemes) {
names.add(scheme.getName())
names.add(scheme.name)
}
return names
}
@@ -870,9 +868,9 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
private fun ExternalizableScheme.renameScheme(newName: String) {
if (newName != getName()) {
setName(newName)
LOG.assertTrue(newName == getName())
if (newName != name) {
name = newName
LOG.assertTrue(newName == name)
}
}
@@ -885,15 +883,11 @@ private inline fun MutableList<Throwable>.catch(runnable: () -> Unit) {
}
}
inline val Scheme.name: String
get() = getName()
fun createDir(ioDir: File, requestor: Any): VirtualFile {
ioDir.mkdirs()
val parentFile = ioDir.getParent()
val parentVirtualFile = (if (parentFile == null) null else VfsUtil.createDirectoryIfMissing(parentFile)) ?: throw IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile))
return getFile(ioDir.getName(), parentVirtualFile, requestor)
return getFile(ioDir.name, parentVirtualFile, requestor)
}
fun getFile(fileName: String, parent: VirtualFile, requestor: Any): VirtualFile {
Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

@@ -246,8 +246,9 @@ public abstract class RunConfigurationProducer<T extends RunConfiguration> {
@Nullable
public RunConfiguration createLightConfiguration(@NotNull final ConfigurationContext context) {
RunConfiguration configuration = myConfigurationFactory.createTemplateConfiguration(context.getProject());
final Ref<PsiElement> ref = new Ref<PsiElement>(context.getPsiLocation());
try {
if (!setupConfigurationFromContext((T)configuration, context, new Ref<PsiElement>(context.getPsiLocation()))) {
if (!setupConfigurationFromContext((T)configuration, context, ref)) {
return null;
}
}
@@ -230,9 +230,12 @@ public class RenameProcessor extends BaseRefactoringProcessor {
}
private boolean findRenamedVariables(final List<UsageInfo> variableUsages) {
for (final AutomaticRenamer automaticVariableRenamer : myRenamers) {
for (Iterator<AutomaticRenamer> iterator = myRenamers.iterator(); iterator.hasNext(); ) {
AutomaticRenamer automaticVariableRenamer = iterator.next();
if (!automaticVariableRenamer.hasAnythingToRename()) continue;
if (!showAutomaticRenamingDialog(automaticVariableRenamer)) return false;
if (!showAutomaticRenamingDialog(automaticVariableRenamer)) {
iterator.remove();
}
}
final Runnable runnable = new Runnable() {
@@ -241,7 +241,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
final AutomaticRenamingDialog renamingDialog = new AutomaticRenamingDialog(myProject, renamer);
if (!renamingDialog.showAndGet()) {
return;
continue;
}
}
@@ -24,7 +24,9 @@ import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.sun.jna.Library.OPTION_FUNCTION_MAPPER;
@@ -123,8 +125,15 @@ public class WindowsCryptUtils {
DATA_BLOB pDataOut);
class DATA_BLOB extends Structure implements Structure.ByReference {
private static final List __FIELDS = Arrays.asList("cbData", "pbData");
public W32API.DWORD cbData;
public Pointer pbData;
@Override
protected List getFieldOrder() {
return __FIELDS;
}
}
}
@@ -57,8 +57,8 @@ public final class EditorUtil {
* @return true if the editor is in fact an ordinary file editor;
* false if the editor is part of EditorTextField, CommitMessage and etc.
*/
public static boolean isRealFileEditor(@NotNull Editor editor) {
return TextEditorProvider.getInstance().getTextEditor(editor) instanceof TextEditorImpl;
public static boolean isRealFileEditor(@Nullable Editor editor) {
return editor != null && TextEditorProvider.getInstance().getTextEditor(editor) instanceof TextEditorImpl;
}
public static int getLastVisualLineColumnNumber(@NotNull Editor editor, final int line) {
@@ -40,6 +40,8 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
private final Map<String, SMTestProxy> myRunningTestsFullNameToProxy = new HashMap<String, SMTestProxy>();
private final Set<AbstractTestProxy> myFailedTestsSet = new HashSet<AbstractTestProxy>();
private final TestSuiteStack mySuitesStack;
private final Set<SMTestProxy> myCurrentChildren = new LinkedHashSet<SMTestProxy>();
private boolean myGetChildren = true;
private final SMTestProxy.SMRootTestProxy myTestsRootNode;
private boolean myIsTestingFinished;
@@ -231,6 +233,15 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
}
parentSuite.addChild(testProxy);
if (myTreeBuildBeforeStart && myGetChildren) {
for (SMTestProxy proxy : parentSuite.getChildren()) {
if (!proxy.isFinal()) {
myCurrentChildren.add(proxy);
}
}
myGetChildren = false;
}
}
// adds to running tests map
@@ -264,6 +275,7 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
parentSuite.addChild(newSuite);
}
myGetChildren = true;
mySuitesStack.pushSuite(newSuite);
//Progress started
@@ -277,7 +289,8 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
private SMTestProxy findChildByName(SMTestProxy parentSuite, String fullName) {
if (myTreeBuildBeforeStart) {
for (SMTestProxy proxy : parentSuite.getChildren()) {
final Collection<? extends SMTestProxy> children = myGetChildren ? parentSuite.getChildren() : myCurrentChildren;
for (SMTestProxy proxy : children) {
if (fullName.equals(proxy.getName()) && !proxy.isFinal()) {
return proxy;
}
@@ -303,6 +316,7 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
testProxy.setDuration(duration);
testProxy.setFinished();
myRunningTestsFullNameToProxy.remove(fullTestName);
myCurrentChildren.remove(testProxy);
//fire events
fireOnTestFinished(testProxy);
@@ -317,6 +331,7 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
final SMTestProxy mySuite = mySuitesStack.popSuite(suiteName);
if (mySuite != null) {
mySuite.setFinished();
myCurrentChildren.clear();
//fire events
fireOnSuiteFinished(mySuite);
@@ -412,13 +412,15 @@ public class SMTestProxy extends AbstractTestProxy {
* @param duration In milliseconds
*/
public void setDuration(final long duration) {
invalidateCachedDurationForContainerSuites();
if (!isSuite()) {
invalidateCachedDurationForContainerSuites(duration - (myDuration != null ? myDuration : 0));
myDurationIsCached = true;
myDuration = (duration >= 0) ? duration : null;
return;
}
else {
invalidateCachedDurationForContainerSuites(-1);
}
// Not allow to directly set duration for suites.
// It should be the sum of children. This requirement is only
@@ -782,17 +784,28 @@ public class SMTestProxy extends AbstractTestProxy {
}
/**
* Recursively invalidates cached duration for container(parent) suites
* Recursively invalidates cached duration for container(parent) suites or updates their value
* @param duration
*/
private void invalidateCachedDurationForContainerSuites() {
// Invalidates duration of this suite
myDuration = null;
myDurationIsCached = false;
private void invalidateCachedDurationForContainerSuites(long duration) {
if (duration >= 0) {
if (myDuration == null) {
myDuration = duration;
}
else {
myDuration += duration;
}
}
else {
// Invalidates duration of this suite
myDuration = null;
myDurationIsCached = false;
}
// Invalidates duration of container suite
final SMTestProxy containerSuite = getParent();
if (containerSuite != null) {
containerSuite.invalidateCachedDurationForContainerSuites();
containerSuite.invalidateCachedDurationForContainerSuites(duration);
}
}
@@ -801,7 +814,7 @@ public class SMTestProxy extends AbstractTestProxy {
while (parent != null && !(parent instanceof SMRootTestProxy)) {
parent = parent.getParent();
}
return parent instanceof SMRootTestProxy ? (SMRootTestProxy)parent : null;
return parent != null ? (SMRootTestProxy)parent : null;
}
public static class SMRootTestProxy extends SMTestProxy implements TestProxyRoot {
@@ -283,32 +283,24 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
@Override
protected void setUp() throws Exception {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
@Override
public void run() {
try {
LightPlatformTestCase.super.setUp();
initApplication();
ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest());
public void run() throws Exception {
LightPlatformTestCase.super.setUp();
initApplication();
ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest());
ourApplication.setDataProvider(LightPlatformTestCase.this);
LightProjectDescriptor descriptor = new SimpleLightProjectDescriptor(getModuleType(), getProjectJDK());
doSetup(descriptor, configureLocalInspectionTools(), getTestRootDisposable());
InjectedLanguageManagerImpl.pushInjectors(getProject());
ourApplication.setDataProvider(LightPlatformTestCase.this);
LightProjectDescriptor descriptor = new SimpleLightProjectDescriptor(getModuleType(), getProjectJDK());
doSetup(descriptor, configureLocalInspectionTools(), getTestRootDisposable());
InjectedLanguageManagerImpl.pushInjectors(getProject());
storeSettings();
storeSettings();
myThreadTracker = new ThreadTracker();
ModuleRootManager.getInstance(ourModule).orderEntries().getAllLibrariesAndSdkClassesRoots();
VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
filePointerManager.storePointers();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
myThreadTracker = new ThreadTracker();
ModuleRootManager.getInstance(ourModule).orderEntries().getAllLibrariesAndSdkClassesRoots();
VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
filePointerManager.storePointers();
}
});
}
@@ -264,18 +264,25 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
@NotNull
public static Project createProject(@NotNull String path, String creationPlace) {
return createProject(path, creationPlace, false);
}
@NotNull
public static Project createProject(@NotNull String path, String creationPlace, boolean clearVfs) {
String fileName = PathUtilRt.getFileName(path);
String projectName = FileUtilRt.getNameWithoutExtension(fileName);
VirtualFile projectBase = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(fileName.endsWith(
ProjectFileType.DOT_DEFAULT_EXTENSION) ? PathUtilRt.getParentPath(path) : path));
if (projectBase != null) {
// must be leftovers from the previous test run
for (VirtualFile file : ((NewVirtualFile)projectBase).iterInDbChildren()) {
delete(file);
if (clearVfs) {
VirtualFile projectBase = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(fileName.endsWith(
ProjectFileType.DOT_DEFAULT_EXTENSION) ? PathUtilRt.getParentPath(path) : path));
if (projectBase != null) {
// must be leftovers from the previous test run
for (VirtualFile file : ((NewVirtualFile)projectBase).iterInDbChildren()) {
delete(file);
}
}
}
try {
String projectName = FileUtilRt.getNameWithoutExtension(fileName);
Project project = ProjectManagerEx.getInstanceEx().newProject(projectName, path, false, false);
assert project != null;
@@ -136,7 +136,7 @@ public abstract class UsefulTestCase extends TestCase {
super.setUp();
if (shouldContainTempFiles()) {
String testName = getTestName(true);
String testName = FileUtil.sanitizeFileName(getTestName(true));
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
testName = new File(testName).getName(); // in case the test name contains file separators
File tempDirectory = FileUtil.createTempDirectory(new File(ORIGINAL_TEMP_DIR), TEMP_DIR_MARKER + testName, "");
@@ -72,7 +72,7 @@ public class ProjectRule() : ExternalResource() {
val buffer = ByteArrayOutputStream()
java.lang.Throwable(projectPath).printStackTrace(PrintStream(buffer))
val project = PlatformTestCase.createProject(projectPath, "Light project: $buffer") as ProjectEx
val project = PlatformTestCase.createProject(projectPath, "Light project: $buffer", false) as ProjectEx
Disposer.register(ApplicationManager.getApplication(), Disposable {
try {
disposeProject()
@@ -557,6 +557,7 @@ public class AllIcons {
public static final Icon Colors = IconLoader.getIcon("/gutter/colors.png"); // 12x12
public static final Icon ExtAnnotation = IconLoader.getIcon("/gutter/extAnnotation.png"); // 12x12
public static final Icon ImplementedMethod = IconLoader.getIcon("/gutter/implementedMethod.png"); // 12x12
public static final Icon ImplementingFunctional = IconLoader.getIcon("/gutter/implementingFunctional.png"); // 12x12
public static final Icon ImplementingMethod = IconLoader.getIcon("/gutter/implementingMethod.png"); // 12x12
public static final Icon OverridenMethod = IconLoader.getIcon("/gutter/overridenMethod.png"); // 12x12
public static final Icon OverridingMethod = IconLoader.getIcon("/gutter/overridingMethod.png"); // 12x12
@@ -439,7 +439,7 @@ public class PathManager {
THashSet.class, // trove4j
PicoContainer.class, // PicoContainer
TypeMapper.class, // JNA
FileUtils.class, // JNA (jna-utils)
FileUtils.class, // JNA (jna-platform)
PatternMatcher.class, // OROMatcher
Snappy.class // Snappy
};
@@ -23,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
@@ -350,6 +352,8 @@ public class Foundation {
}
public static class NSRect extends Structure implements Structure.ByValue {
private static final List __FIELDS = Arrays.asList("origin", "size");
public NSPoint origin;
public NSSize size;
@@ -357,9 +361,16 @@ public class Foundation {
origin = new NSPoint(x, y);
size = new NSSize(w, h);
}
@Override
protected List getFieldOrder() {
return __FIELDS;
}
}
public static class NSPoint extends Structure implements Structure.ByValue {
private static final List __FIELDS = Arrays.asList("x", "y");
public CGFloat x;
public CGFloat y;
@@ -372,9 +383,16 @@ public class Foundation {
this.x = new CGFloat(x);
this.y = new CGFloat(y);
}
@Override
protected List getFieldOrder() {
return __FIELDS;
}
}
public static class NSSize extends Structure implements Structure.ByValue {
private static final List __FIELDS = Arrays.asList("width", "height");
public CGFloat width;
public CGFloat height;
@@ -387,6 +405,11 @@ public class Foundation {
this.width = new CGFloat(width);
this.height = new CGFloat(height);
}
@Override
protected List getFieldOrder() {
return __FIELDS;
}
}
public static class CGFloat implements NativeMapped {
+10 -10
View File
@@ -46,9 +46,9 @@ import kotlin.properties.Delegates
val PLUGIN_NAME: String = "Settings Repository"
val LOG: Logger = Logger.getInstance(IcsManager::class.java)
internal val LOG: Logger = Logger.getInstance(IcsManager::class.java)
val icsManager by Delegates.lazy {
val icsManager by lazy(LazyThreadSafetyMode.NONE) {
ApplicationLoadListener.EP_NAME.findExtension(IcsApplicationLoadListener::class.java).icsManager
}
@@ -101,15 +101,15 @@ class IcsManager(dir: File) {
}
}, settings.commitDelay)
private volatile var autoCommitEnabled = true
private @Volatile var autoCommitEnabled = true
volatile var repositoryActive = false
@Volatile var repositoryActive = false
val autoSyncManager = AutoSyncManager(this)
private val syncManager = SyncManager(this, autoSyncManager)
private fun scheduleCommit() {
if (autoCommitEnabled && !ApplicationManager.getApplication()!!.isUnitTestMode()) {
if (autoCommitEnabled && !ApplicationManager.getApplication()!!.isUnitTestMode) {
commitAlarm.cancelAndRequest()
}
}
@@ -160,13 +160,13 @@ class IcsManager(dir: File) {
fun beforeApplicationLoaded(application: Application) {
repositoryActive = repositoryManager.isRepositoryExists()
(application.stateStore.getStateStorageManager() as StateStorageManagerImpl).streamProvider = ApplicationLevelProvider()
(application.stateStore.stateStorageManager as StateStorageManagerImpl).streamProvider = ApplicationLevelProvider()
autoSyncManager.registerListeners(application)
application.getMessageBus().connect().subscribe(ProjectLifecycleListener.TOPIC, object : ProjectLifecycleListener.Adapter() {
application.messageBus.connect().subscribe(ProjectLifecycleListener.TOPIC, object : ProjectLifecycleListener.Adapter() {
override fun beforeProjectLoaded(project: Project) {
if (project.isDefault()) {
if (project.isDefault) {
return
}
@@ -223,7 +223,7 @@ class IcsApplicationLoadListener : ApplicationLoadListener {
private set
override fun beforeApplicationLoaded(application: Application, configPath: String) {
if (application.isUnitTestMode()) {
if (application.isUnitTestMode) {
return
}
@@ -263,7 +263,7 @@ class IcsApplicationLoadListener : ApplicationLoadListener {
Pair("_unknown/\$APP_CONFIG$", "_unknown")
))) {
// schedule push to avoid merge conflicts
application.invokeLater(Runnable { icsManager.autoSyncManager.autoSync(force = true) })
application.invokeLater({ icsManager.autoSyncManager.autoSync(force = true) })
}
}
+14 -14
View File
@@ -35,19 +35,19 @@ import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier
import java.util.concurrent.Future
class AutoSyncManager(private val icsManager: IcsManager) {
private volatile var autoSyncFuture: Future<*>? = null
private @Volatile var autoSyncFuture: Future<*>? = null
fun waitAutoSync(indicator: ProgressIndicator) {
val autoFuture = autoSyncFuture
if (autoFuture != null) {
if (autoFuture.isDone()) {
if (autoFuture.isDone) {
autoSyncFuture = null
}
else if (autoSyncFuture != null) {
LOG.info("Wait for auto sync future")
indicator.setText("Wait for auto sync completion")
while (!autoFuture.isDone()) {
if (indicator.isCanceled()) {
indicator.text = "Wait for auto sync completion"
while (!autoFuture.isDone) {
if (indicator.isCanceled) {
return
}
Thread.sleep(5)
@@ -65,21 +65,21 @@ class AutoSyncManager(private val icsManager: IcsManager) {
}
fun registerListeners(project: Project) {
project.getMessageBus().connect().subscribe(Notifications.TOPIC, object : NotificationsAdapter() {
project.messageBus.connect().subscribe(Notifications.TOPIC, object : NotificationsAdapter() {
override fun notify(notification: Notification) {
if (!icsManager.repositoryActive || project.isDisposed()) {
if (!icsManager.repositoryActive || project.isDisposed) {
return
}
if (when {
notification.getGroupId() == VcsBalloonProblemNotifier.NOTIFICATION_GROUP.getDisplayId() -> {
val message = notification.getContent()
notification.groupId == VcsBalloonProblemNotifier.NOTIFICATION_GROUP.displayId -> {
val message = notification.content
message.startsWith("VCS Update Finished") ||
message == VcsBundle.message("message.text.file.is.up.to.date") ||
message == VcsBundle.message("message.text.all.files.are.up.to.date")
}
notification.getGroupId() == VcsNotifier.NOTIFICATION_GROUP_ID.getDisplayId() && notification.getTitle() == "Push successful" -> true
notification.groupId == VcsNotifier.NOTIFICATION_GROUP_ID.displayId && notification.title == "Push successful" -> true
else -> false
}) {
@@ -95,7 +95,7 @@ class AutoSyncManager(private val icsManager: IcsManager) {
}
var future = autoSyncFuture
if (future != null && !future.isDone()) {
if (future != null && !future.isDone) {
return
}
@@ -105,7 +105,7 @@ class AutoSyncManager(private val icsManager: IcsManager) {
sync(app, onAppExit)
return
}
else if (app.isDisposeInProgress()) {
else if (app.isDisposeInProgress) {
// will be handled by applicationExiting listener
return
}
@@ -145,7 +145,7 @@ class AutoSyncManager(private val icsManager: IcsManager) {
app.invokeAndWait({
catchAndLog {
val updateResult = updater.merge()
if (!onAppExit && !app.isDisposeInProgress() && updateResult != null && updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult, app.getMessageBus())) {
if (!onAppExit && !app.isDisposeInProgress && updateResult != null && updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) {
// force to avoid saveAll & confirmation
app.exit(true, true, true, true)
}
@@ -160,7 +160,7 @@ class AutoSyncManager(private val icsManager: IcsManager) {
}
}
inline fun catchAndLog(runnable: () -> Unit) {
inline internal fun catchAndLog(runnable: () -> Unit) {
try {
runnable()
}
+6 -6
View File
@@ -31,10 +31,10 @@ import com.intellij.openapi.util.Computable
import com.intellij.util.messages.MessageBus
import com.intellij.util.ui.UIUtil
import gnu.trove.THashSet
import java.util.LinkedHashSet
import java.util.*
class SyncManager(private val icsManager: IcsManager, private val autoSyncManager: AutoSyncManager) {
volatile var writeAndDeleteProhibited = false
@Volatile var writeAndDeleteProhibited = false
private set
public fun sync(syncType: SyncType, project: Project? = null, localRepositoryInitializer: (() -> Unit)? = null): UpdateResult? {
@@ -47,7 +47,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage
writeAndDeleteProhibited = true
ProgressManager.getInstance().run(object : Task.Modal(project, IcsBundle.message("task.sync.title"), true) {
override fun run(indicator: ProgressIndicator) {
indicator.setIndeterminate(true)
indicator.isIndeterminate = true
autoSyncManager.waitAutoSync(indicator)
@@ -73,7 +73,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage
}
}
if (indicator.isCanceled()) {
if (indicator.isCanceled) {
return
}
@@ -114,7 +114,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage
icsManager.repositoryActive = true
if (updateResult != null) {
val app = ApplicationManager.getApplication()
restartApplication = updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult!!, app.getMessageBus())
restartApplication = updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult!!, app.messageBus)
}
if (!restartApplication && syncType == SyncType.OVERWRITE_LOCAL) {
(SchemesManagerFactory.getInstance() as SchemeManagerFactoryBase).process {
@@ -140,7 +140,7 @@ class SyncManager(private val icsManager: IcsManager, private val autoSyncManage
}
}
private fun updateStoragesFromStreamProvider(store: ComponentStoreImpl, updateResult: UpdateResult, messageBus: MessageBus): Boolean {
internal fun updateStoragesFromStreamProvider(store: ComponentStoreImpl, updateResult: UpdateResult, messageBus: MessageBus): Boolean {
val changedComponentNames = LinkedHashSet<String>()
val (changed, deleted) = (store.storageManager as StateStorageManagerImpl).getCachedFileStorages(updateResult.changed, updateResult.deleted)
if (changed.isEmpty() && deleted.isEmpty()) {
@@ -1,4 +1,5 @@
This is a README.txt file for SQLJet v1.0.4.
This is a README.txt file for SQLJet (c) 2009-2013 TMate Software.
SQLJet is a pure Java (tm) embedded database management engine with SQLite format support.
1. DESCRIPTION
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -42,6 +42,7 @@ public class SvnKitBrowseClient extends BaseSvnClient implements BrowseClient {
SVNLogClient client = getLogClient();
ISVNDirEntryHandler wrappedHandler = wrapHandler(handler);
client.setIgnoreExternals(true);
try {
if (target.isFile()) {
client.doList(target.getFile(), target.getPegRevision(), notNullize(revision), true, toDepth(depth), SVNDirEntry.DIRENT_ALL, wrappedHandler);
@@ -9,9 +9,12 @@ import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.api.ProgressTracker;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb;
import org.tmatesoft.svn.core.internal.wc2.SvnWcGeneration;
import org.tmatesoft.svn.core.internal.wc2.compat.SvnCodec;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc2.SvnCheckout;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
@@ -49,21 +52,59 @@ public class SvnKitCheckoutClient extends BaseSvnClient implements CheckoutClien
SVNUpdateClient client = myVcs.getSvnKitManager().createUpdateClient();
if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) {
client.getOperationsFactory().setPrimaryWcGeneration(SvnWcGeneration.V16);
}
client.setIgnoreExternals(ignoreExternals);
client.setEventHandler(toEventHandler(handler));
try {
client.doCheckout(source.getURL(), destination, source.getPegRevision(), revision, toDepth(depth), force);
runCheckout(client, format, source, destination, revision, depth, force);
}
catch (SVNException e) {
throw new SvnBindException(e);
}
}
/**
* This is mostly inlined {@code SVNUpdateClient.doCheckout()} - to allow specifying necessary working copy format. Otherwise, if only
* {@link SvnWcGeneration} is used - either svn 1.6 or svn 1.8 working copy will be created.
* <p/>
* See also http://issues.tmatesoft.com/issue/SVNKIT-495 for more details.
*/
private static void runCheckout(@NotNull SVNUpdateClient client,
@NotNull WorkingCopyFormat format,
@NotNull SvnTarget source,
@NotNull File destination,
@Nullable SVNRevision revision,
@Nullable Depth depth,
boolean force) throws SVNException {
SvnCheckout checkoutOperation = createCheckoutOperation(client, format);
checkoutOperation.setUpdateLocksOnDemand(client.isUpdateLocksOnDemand());
checkoutOperation.setSource(SvnTarget.fromURL(source.getURL(), source.getPegRevision()));
checkoutOperation.setSingleTarget(SvnTarget.fromFile(destination));
checkoutOperation.setRevision(revision);
checkoutOperation.setDepth(toDepth(depth));
checkoutOperation.setAllowUnversionedObstructions(force);
checkoutOperation.setIgnoreExternals(client.isIgnoreExternals());
checkoutOperation.setExternalsHandler(SvnCodec.externalsHandler(client.getExternalsHandler()));
checkoutOperation.run();
}
@NotNull
private static SvnCheckout createCheckoutOperation(@NotNull SVNUpdateClient client, @NotNull WorkingCopyFormat format) {
if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) {
client.getOperationsFactory().setPrimaryWcGeneration(SvnWcGeneration.V16);
}
SvnCheckout checkoutOperation = client.getOperationsFactory().createCheckout();
if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
checkoutOperation.setTargetWorkingCopyFormat(ISVNWCDb.WC_FORMAT_17);
}
return checkoutOperation;
}
@Override
public List<WorkingCopyFormat> getSupportedFormats() throws VcsException {
return SUPPORTED_FORMATS;
@@ -2,9 +2,9 @@
QuerySet is parametrized with model object
"""
class QuerySet(object):
def __init__(self):
def __init__(self, model=None, query=None, using=None, hints=None):
"""
:rtype: QuerySet[T]
:rtype: django.db.models.QuerySet[T]
"""
pass
@@ -234,7 +234,7 @@ label.debugger.general.configurable.skip.constructors=Skip &constructors
label.debugger.general.configurable.skip.classLoaders=Skip class l&oaders
label.debugger.general.configurable.skip.simple.getters=Skip simple &getters
label.debugger.general.configurable.step.filters.list.header=Do not step &into the classes
label.debugger.general.configurable.evaluate.finally.on.pop=Evaluate finally blocks on pop frame:
label.debugger.general.configurable.evaluate.finally.on.pop=Evaluate finally blocks on pop frame and early return:
label.debugger.general.configurable.evaluate.finally.always=&Always
label.debugger.general.configurable.evaluate.finally.never=N&ever
label.debugger.general.configurable.evaluate.finally.ask=As&k
@@ -21,6 +21,9 @@ import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
import java.util.Arrays;
import java.util.List;
public interface Win32RestartManager extends Library {
Win32RestartManager INSTANCE = (Win32RestartManager) Native.loadLibrary("Rstrtmgr", Win32RestartManager.class);
@@ -30,11 +33,21 @@ public interface Win32RestartManager extends Library {
int CCH_RM_MAX_SVC_NAME = 63;
class RmUniqueProcess extends Structure {
private static final List __FIELDS = Arrays.asList("dwProcessId", "ProcessStartTime");
public int dwProcessId;
public WinBase.FILETIME ProcessStartTime;
@Override
protected List getFieldOrder() {
return __FIELDS;
}
}
class RmProcessInfo extends Structure {
private static final List __FIELDS = Arrays.asList(
"Process", "strAppName", "strServiceShortName", "ApplicationType", "AppStatus", "TSSessionId", "bRestartable");
public RmUniqueProcess Process;
public char[] strAppName = new char[CCH_RM_MAX_APP_NAME + 1];
public char[] strServiceShortName = new char[CCH_RM_MAX_SVC_NAME + 1];
@@ -42,6 +55,11 @@ public interface Win32RestartManager extends Library {
public WinDef.LONG AppStatus;
public int TSSessionId;
public boolean bRestartable;
@Override
protected List getFieldOrder() {
return __FIELDS;
}
}
int RmGetList(int dwSessionHandle,