summaryrefslogtreecommitdiff
path: root/json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java
diff options
context:
space:
mode:
authorAndrej Shadura <andrew.shadura@collabora.co.uk>2019-08-28 14:13:29 +0200
committerAndrej Shadura <andrew.shadura@collabora.co.uk>2019-08-29 17:48:13 +0200
commite19ef5983707e6a5c8d127f1ac8f02754cef82fd (patch)
tree9e3852cb9abc81ed6aa444465928d45fd7763dea /json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java
New upstream version 0~183.5153.4+dfsg
Diffstat (limited to 'json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java')
-rw-r--r--json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java323
1 files changed, 323 insertions, 0 deletions
diff --git a/json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java b/json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java
new file mode 100644
index 00000000..8ab70270
--- /dev/null
+++ b/json/src/com/jetbrains/jsonSchema/UserDefinedJsonSchemaConfiguration.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2000-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.jsonSchema;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.AtomicClearableLazyValue;
+import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.PatternUtil;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xmlb.annotations.Tag;
+import com.intellij.util.xmlb.annotations.Transient;
+import com.jetbrains.jsonSchema.ide.JsonSchemaService;
+import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
+import com.jetbrains.jsonSchema.impl.JsonSchemaVersion;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * @author Irina.Chernushina on 4/19/2017.
+ */
+@Tag("SchemaInfo")
+public class UserDefinedJsonSchemaConfiguration {
+ private final static Comparator<Item> ITEM_COMPARATOR = (o1, o2) -> {
+ if (o1.isPattern() != o2.isPattern()) return o1.isPattern() ? -1 : 1;
+ if (o1.isDirectory() != o2.isDirectory()) return o1.isDirectory() ? -1 : 1;
+ return o1.path.compareToIgnoreCase(o2.path);
+ };
+
+ public String name;
+ public String relativePathToSchema;
+ public JsonSchemaVersion schemaVersion = JsonSchemaVersion.SCHEMA_4;
+ public boolean applicationDefined;
+ public List<Item> patterns = new SmartList<>();
+ @Transient
+ private final AtomicClearableLazyValue<List<PairProcessor<Project, VirtualFile>>> myCalculatedPatterns =
+ new AtomicClearableLazyValue<List<PairProcessor<Project, VirtualFile>>>() {
+ @NotNull
+ @Override
+ protected List<PairProcessor<Project, VirtualFile>> compute() {
+ return recalculatePatterns();
+ }
+ };
+
+ public UserDefinedJsonSchemaConfiguration() {
+ }
+
+ public UserDefinedJsonSchemaConfiguration(@NotNull String name,
+ JsonSchemaVersion schemaVersion,
+ @NotNull String relativePathToSchema,
+ boolean applicationDefined,
+ @Nullable List<Item> patterns) {
+ this.name = name;
+ this.relativePathToSchema = relativePathToSchema;
+ this.schemaVersion = schemaVersion;
+ this.applicationDefined = applicationDefined;
+ setPatterns(patterns);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(@NotNull String name) {
+ this.name = name;
+ }
+
+ public String getRelativePathToSchema() {
+ return relativePathToSchema;
+ }
+
+ public JsonSchemaVersion getSchemaVersion() {
+ return schemaVersion;
+ }
+
+ public void setSchemaVersion(JsonSchemaVersion schemaVersion) {
+ this.schemaVersion = schemaVersion;
+ }
+
+ public void setRelativePathToSchema(String relativePathToSchema) {
+ this.relativePathToSchema = relativePathToSchema;
+ }
+
+ public boolean isApplicationDefined() {
+ return applicationDefined;
+ }
+
+ public void setApplicationDefined(boolean applicationDefined) {
+ this.applicationDefined = applicationDefined;
+ }
+
+ public List<Item> getPatterns() {
+ return patterns;
+ }
+
+ public void setPatterns(@Nullable List<Item> patterns) {
+ this.patterns.clear();
+ if (patterns != null) this.patterns.addAll(patterns);
+ Collections.sort(this.patterns, ITEM_COMPARATOR);
+ myCalculatedPatterns.drop();
+ }
+
+ public void refreshPatterns() {
+ myCalculatedPatterns.drop();
+ }
+
+ @NotNull
+ public List<PairProcessor<Project, VirtualFile>> getCalculatedPatterns() {
+ return myCalculatedPatterns.getValue();
+ }
+
+ private List<PairProcessor<Project, VirtualFile>> recalculatePatterns() {
+ final List<PairProcessor<Project, VirtualFile>> result = new SmartList<>();
+ for (final Item patternText : patterns) {
+ switch (patternText.mappingKind) {
+ case File:
+ result.add((project, vfile) -> vfile.equals(getRelativeFile(project, patternText)) || vfile.getUrl().equals(patternText.getPath()));
+ break;
+ case Pattern:
+ String pathText = patternText.getPath().replace(File.separatorChar, '/').replace('\\', '/');
+ final Pattern pattern = pathText.isEmpty()
+ ? PatternUtil.NOTHING
+ : pathText.indexOf('/') >= 0
+ ? PatternUtil.compileSafe(".*/" + PatternUtil.convertToRegex(pathText), PatternUtil.NOTHING)
+ : PatternUtil.fromMask(pathText);
+ result.add((project, file) -> JsonSchemaObject.matchPattern(pattern, pathText.indexOf('/') >= 0
+ ? file.getPath()
+ : file.getName()));
+ break;
+ case Directory:
+ result.add((project, vfile) -> {
+ final VirtualFile relativeFile = getRelativeFile(project, patternText);
+ if (relativeFile == null || !VfsUtilCore.isAncestor(relativeFile, vfile, true)) return false;
+ JsonSchemaService service = JsonSchemaService.Impl.get(project);
+ return service.isApplicableToFile(vfile);
+ });
+ break;
+ }
+ }
+ return result;
+ }
+
+ @Nullable
+ private static VirtualFile getRelativeFile(@NotNull final Project project, @NotNull final Item pattern) {
+ if (project.getBasePath() == null) {
+ return null;
+ }
+
+ final String path = FileUtilRt.toSystemIndependentName(StringUtil.notNullize(pattern.path));
+ final List<String> parts = pathToPartsList(path);
+ if (parts.isEmpty()) {
+ return project.getBaseDir();
+ }
+ else {
+ return VfsUtil.findRelativeFile(project.getBaseDir(), ArrayUtil.toStringArray(parts));
+ }
+ }
+
+ @NotNull
+ private static List<String> pathToPartsList(@NotNull String path) {
+ return ContainerUtil.filter(StringUtil.split(path, "/"), s -> !".".equals(s));
+ }
+
+ @NotNull
+ private static String[] pathToParts(@NotNull String path) {
+ return ArrayUtil.toStringArray(pathToPartsList(path));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ UserDefinedJsonSchemaConfiguration info = (UserDefinedJsonSchemaConfiguration)o;
+
+ if (applicationDefined != info.applicationDefined) return false;
+ if (schemaVersion != info.schemaVersion) return false;
+ if (!Objects.equals(name, info.name)) return false;
+ if (!Objects.equals(relativePathToSchema, info.relativePathToSchema)) return false;
+
+ return Objects.equals(patterns, info.patterns);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (relativePathToSchema != null ? relativePathToSchema.hashCode() : 0);
+ result = 31 * result + (applicationDefined ? 1 : 0);
+ result = 31 * result + (patterns != null ? patterns.hashCode() : 0);
+ result = 31 * result + schemaVersion.hashCode();
+ return result;
+ }
+
+ public static class Item {
+ public String path;
+ public JsonMappingKind mappingKind = JsonMappingKind.File;
+
+ public Item() {
+ }
+
+ public Item(String path, JsonMappingKind mappingKind) {
+ this.path = neutralizePath(path);
+ this.mappingKind = mappingKind;
+ }
+
+ public Item(String path, boolean isPattern, boolean isDirectory) {
+ this.path = neutralizePath(path);
+ this.mappingKind = isPattern ? JsonMappingKind.Pattern : isDirectory ? JsonMappingKind.Directory : JsonMappingKind.File;
+ }
+
+ @NotNull
+ private static String normalizePath(String path) {
+ if (preserveSlashes(path)) return path;
+ return StringUtil.trimEnd(FileUtilRt.toSystemDependentName(path), File.separatorChar);
+ }
+
+ private static boolean preserveSlashes(String path) {
+ // http/https URLs to schemas
+ // mock URLs of fragments editor
+ return StringUtil.startsWith(path, "http:")
+ || StringUtil.startsWith(path, "https:")
+ || StringUtil.startsWith(path, "mock:");
+ }
+
+ @NotNull
+ private static String neutralizePath(String path) {
+ if (preserveSlashes(path)) return path;
+ return StringUtil.trimEnd(FileUtilRt.toSystemIndependentName(path), '/');
+ }
+
+ public String getPath() {
+ return normalizePath(path);
+ }
+
+ public void setPath(String path) {
+ this.path = neutralizePath(path);
+ }
+
+ public String getError() {
+ switch (mappingKind) {
+ case File:
+ return !StringUtil.isEmpty(path) ? null : "Empty file path doesn't match anything";
+ case Pattern:
+ return !StringUtil.isEmpty(path) ? null : "Empty pattern matches nothing";
+ case Directory:
+ return null;
+ }
+
+ return "Unknown mapping kind";
+ }
+
+ public boolean isPattern() {
+ return mappingKind == JsonMappingKind.Pattern;
+ }
+
+ public void setPattern(boolean pattern) {
+ mappingKind = pattern ? JsonMappingKind.Pattern : JsonMappingKind.File;
+ }
+
+ public boolean isDirectory() {
+ return mappingKind == JsonMappingKind.Directory;
+ }
+
+ public void setDirectory(boolean directory) {
+ mappingKind = directory ? JsonMappingKind.Directory : JsonMappingKind.File;
+ }
+
+ public String getPresentation() {
+ if (mappingKind == JsonMappingKind.Directory && StringUtil.isEmpty(path)) {
+ return mappingKind.getPrefix() + "[Project Directory]";
+ }
+ return mappingKind.getPrefix() + getPath();
+ }
+
+ public String[] getPathParts() {
+ return pathToParts(path);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Item item = (Item)o;
+
+ if (mappingKind != item.mappingKind) return false;
+ return Objects.equals(path, item.path);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hashCode(path);
+ result = 31 * result + Objects.hashCode(mappingKind);
+ return result;
+ }
+ }
+}