Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSnjezana Peco2016-07-15 17:50:01 +0000
committerVictor Rubezhny2016-08-11 17:11:25 +0000
commite8b15c416f126c29416fdee94c3413f3584bba34 (patch)
tree46d92da2b94e0bca7683c3cb792e00953b6e516b
parentca363be313f7b70208b5c5c8d5b891698de9f62f (diff)
downloadwebtools.sourceediting-e8b15c416f126c29416fdee94c3413f3584bba34.tar.gz
webtools.sourceediting-e8b15c416f126c29416fdee94c3413f3584bba34.tar.xz
webtools.sourceediting-e8b15c416f126c29416fdee94c3413f3584bba34.zip
Bug 494110 - Support for JSON Schema Catalog
Change-Id: Ib63761cb3a6f97c13e54e224eabe1d2266b82a40 Signed-off-by: Snjezana Peco <snjeza.peco@gmail.com>
-rw-r--r--bundles/org.eclipse.wst.json.core/META-INF/MANIFEST.MF30
-rw-r--r--bundles/org.eclipse.wst.json.core/schemastore/catalog.json488
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/download/HttpClientProvider.java211
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/Catalog.java39
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogElement.java25
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogSchemastoreReader.java128
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogUserCatalogReader.java42
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/EntryParser.java138
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntries.java26
-rw-r--r--bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntry.java45
-rw-r--r--bundles/org.eclipse.wst.json.schemaprocessor/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.wst.json.schemaprocessor/src/org/eclipse/wst/json/schemaprocessor/internal/JSONSchemaProcessor.java36
-rw-r--r--bundles/org.eclipse.wst.json.ui/META-INF/MANIFEST.MF3
-rw-r--r--bundles/org.eclipse.wst.json.ui/icons/WizBan.pngbin0 -> 5146 bytes
-rw-r--r--bundles/org.eclipse.wst.json.ui/plugin.properties3
-rw-r--r--bundles/org.eclipse.wst.json.ui/plugin.xml12
-rw-r--r--bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.java14
-rw-r--r--bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.properties15
-rw-r--r--bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/EntryDialog.java213
-rw-r--r--bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/JSONCatalogPreferencePage.java263
20 files changed, 1687 insertions, 46 deletions
diff --git a/bundles/org.eclipse.wst.json.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.json.core/META-INF/MANIFEST.MF
index df42eda859..33e79afa8e 100644
--- a/bundles/org.eclipse.wst.json.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.json.core/META-INF/MANIFEST.MF
@@ -12,7 +12,8 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.wst.validation,
org.eclipse.wst.common.uriresolver,
- org.eclipse.json
+ org.eclipse.json,
+ org.eclipse.core.net
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.wst.json.core,
@@ -20,11 +21,38 @@ Export-Package: org.eclipse.wst.json.core,
org.eclipse.wst.json.core.contenttype,
org.eclipse.wst.json.core.document,
org.eclipse.wst.json.core.format,
+ org.eclipse.wst.json.core.internal,
+ org.eclipse.wst.json.core.internal.contenttype,
+ org.eclipse.wst.json.core.internal.document,
+ org.eclipse.wst.json.core.internal.download,
+ org.eclipse.wst.json.core.internal.encoding,
+ org.eclipse.wst.json.core.internal.format,
+ org.eclipse.wst.json.core.internal.modelhandler,
org.eclipse.wst.json.core.internal.parser;x-friends:="org.eclipse.wst.json.core.tests",
+ org.eclipse.wst.json.core.internal.parser.regions,
+ org.eclipse.wst.json.core.internal.preferences,
+ org.eclipse.wst.json.core.internal.schema,
+ org.eclipse.wst.json.core.internal.schema.catalog,
+ org.eclipse.wst.json.core.internal.text,
+ org.eclipse.wst.json.core.internal.util,
+ org.eclipse.wst.json.core.internal.validation,
+ org.eclipse.wst.json.core.internal.validation.core,
+ org.eclipse.wst.json.core.internal.validation.eclipse,
org.eclipse.wst.json.core.jsonpath,
org.eclipse.wst.json.core.modelhandler,
org.eclipse.wst.json.core.preferences,
org.eclipse.wst.json.core.regions,
+ org.eclipse.wst.json.core.schema.catalog,
org.eclipse.wst.json.core.text,
org.eclipse.wst.json.core.util,
org.eclipse.wst.json.core.validation
+Import-Package: org.apache.http,
+ org.apache.http.client,
+ org.apache.http.util,
+ org.apache.http.client.config,
+ org.apache.http.client.methods,
+ org.apache.http.conn,
+ org.apache.http.entity,
+ org.apache.http.impl.client,
+ org.apache.http.conn.routing,
+ org.apache.http.protocol
diff --git a/bundles/org.eclipse.wst.json.core/schemastore/catalog.json b/bundles/org.eclipse.wst.json.core/schemastore/catalog.json
new file mode 100644
index 0000000000..b9026de3a8
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/schemastore/catalog.json
@@ -0,0 +1,488 @@
+{
+ "$schema": "http://json.schemastore.org/schema-catalog",
+
+ "version": 1.0,
+ "schemas": [
+ {
+ "name": "babelrc.json",
+ "description": "Babel configuration file",
+ "fileMatch": [ ".babelrc" ],
+ "url": "http://json.schemastore.org/babelrc"
+ },
+ {
+ "name": ".bootstraprc",
+ "description": "Webpack bootstrap-loader configuration file",
+ "fileMatch": [ ".bootstraprc" ],
+ "url": "http://json.schemastore.org/bootstraprc"
+ },
+ {
+ "name": "bower.json",
+ "description": "Bower package description file",
+ "fileMatch": [ "bower.json", ".bower.json" ],
+ "url": "http://json.schemastore.org/bower"
+ },
+ {
+ "name": ".bowerrc",
+ "description": "Bower configuration file",
+ "fileMatch": [ ".bowerrc" ],
+ "url": "http://json.schemastore.org/bowerrc"
+ },
+ {
+ "name": "bundleconfig.json",
+ "description": "Schema for bundleconfig.json files",
+ "fileMatch": [ "bundleconfig.json" ],
+ "url": "http://json.schemastore.org/bundleconfig"
+ },
+ {
+ "name": "Chrome Extension",
+ "description": "Google Chrome extension manifest file",
+ "url": "http://json.schemastore.org/chrome-manifest"
+ },
+ {
+ "name": "chutzpah.json",
+ "description": "Chutzpah configuration file",
+ "fileMatch": [ "chutzpah.json" ],
+ "url": "http://json.schemastore.org/chutzpah"
+ },
+ {
+ "name": "coffeelint.json",
+ "description": "CoffeeLint configuration file",
+ "fileMatch": [ "coffeelint.json" ],
+ "url": "http://json.schemastore.org/coffeelint"
+ },
+ {
+ "name": "composer.json",
+ "description": "PHP Composer configuration file",
+ "fileMatch": [ "composer.json" ],
+ "url": "http://json.schemastore.org/composer"
+ },
+ {
+ "name": "component.json",
+ "description": "Web component file",
+ "fileMatch": [ "component.json" ],
+ "url": "http://json.schemastore.org/component"
+ },
+ {
+ "name": "config.json",
+ "description": "ASP.NET project config file",
+ "fileMatch": [ "config.json" ],
+ "url": "http://json.schemastore.org/config"
+ },
+ {
+ "name": "contribute.json",
+ "description": "A JSON schema for open-source project contribution data by Mozilla",
+ "fileMatch": [ "contribute.json" ],
+ "url": "http://json.schemastore.org/contribute"
+ },
+ {
+ "name": ".csscomb.json",
+ "description": "A JSON schema CSS Comb's configuration file",
+ "fileMatch": [ ".csscomb.json" ],
+ "url": "http://json.schemastore.org/csscomb"
+ },
+ {
+ "name": ".csslintrc",
+ "description": "A JSON schema CSS Lint's configuration file",
+ "fileMatch": [ ".csslintrc" ],
+ "url": "http://json.schemastore.org/csslintrc"
+ },
+ {
+ "name": "debugsettings.json",
+ "description": "A JSON schema for the ASP.NET DebugSettings.json files",
+ "fileMatch": [ "debugsettings.json" ],
+ "url": "http://json.schemastore.org/launchsettings"
+ },
+ {
+ "name": "epr-manifest.json",
+ "description": "Entry Point Regulation manifest file",
+ "fileMatch": [ "epr-manifest.json" ],
+ "url": "http://json.schemastore.org/epr-manifest"
+ },
+ {
+ "name": ".eslintrc",
+ "description": "JSON schema for ESLint configuration files",
+ "fileMatch": [ ".eslintrc", ".eslintrc.json" ],
+ "url": "http://json.schemastore.org/eslintrc"
+ },
+ {
+ "name": "geojson.json",
+ "description": "GeoJSON format for representing geographic data.",
+ "url": "http://json.schemastore.org/geojson"
+ },
+ {
+ "name": "global.json",
+ "description": "ASP.NET global configuration file",
+ "fileMatch": [ "global.json" ],
+ "url": "http://json.schemastore.org/global"
+ },
+ {
+ "name": "Grunt copy task",
+ "description": "Grunt copy task configuration file",
+ "fileMatch": [ "copy.json" ],
+ "url": "http://json.schemastore.org/grunt-copy-task"
+ },
+ {
+ "name": "Grunt clean task",
+ "description": "Grunt clean task configuration file",
+ "fileMatch": [ "clean.json" ],
+ "url": "http://json.schemastore.org/grunt-clean-task"
+ },
+ {
+ "name": "Grunt cssmin task",
+ "description": "Grunt cssmin task configuration file",
+ "fileMatch": [ "cssmin.json" ],
+ "url": "http://json.schemastore.org/grunt-cssmin-task"
+ },
+ {
+ "name": "Grunt JSHint task",
+ "description": "Grunt JSHint task configuration file",
+ "fileMatch": [ "jshint.json" ],
+ "url": "http://json.schemastore.org/grunt-jshint-task"
+ },
+ {
+ "name": "Grunt Watch task",
+ "description": "Grunt Watch task configuration file",
+ "fileMatch": [ "watch.json" ],
+ "url": "http://json.schemastore.org/grunt-watch-task"
+ },
+ {
+ "name": "Grunt base task",
+ "description": "Schema for standard Grunt tasks",
+ "fileMatch": [ "grunt/*.json", "*-tasks.json" ],
+ "url": "http://json.schemastore.org/grunt-task"
+ },
+ {
+ "name": "haxelib.json",
+ "description": "Haxelib manifest",
+ "fileMatch": [ "haxelib.json" ],
+ "url": "http://json.schemastore.org/haxelib"
+ },
+ {
+ "name": "host-meta.json",
+ "description": "Schema for host-meta JDR files",
+ "fileMatch": [ "host-meta.json" ],
+ "url": "http://json.schemastore.org/host-meta"
+ },
+ {
+ "name": ".htmlhintrc",
+ "description": "HTML Hint configuration file",
+ "fileMatch": [ ".htmlhintrc" ],
+ "url": "http://json.schemastore.org/htmlhint"
+ },
+ {
+ "name": ".jsbeautifyrc",
+ "description": "js-beautify configuration file",
+ "fileMatch": [ ".jsbeautifyrc" ],
+ "url": "http://json.schemastore.org/jsbeautifyrc"
+ },
+ {
+ "name": ".jscsrc",
+ "description": "JSCS configuration file",
+ "fileMatch": [ ".jscsrc", "jscsrc.json" ],
+ "url": "http://json.schemastore.org/jscsrc"
+ },
+ {
+ "name": ".jshintrc",
+ "description": "JSHint configuration file",
+ "fileMatch": [ ".jshintrc" ],
+ "url": "http://json.schemastore.org/jshintrc"
+ },
+ {
+ "name": ".jsinspectrc",
+ "description": "JSInspect configuration file",
+ "fileMatch": [ ".jsinspectrc" ],
+ "url": "http://json.schemastore.org/jsinspectrc"
+ },
+ {
+ "name": "*.jsonld",
+ "description": "JSON Linked Data files",
+ "fileMatch": [ "*.jsonld" ],
+ "url": "http://json.schemastore.org/jsonld"
+ },
+ {
+ "name": "JSONPatch",
+ "description": "JSONPatch files",
+ "fileMatch": [ "*.patch" ],
+ "url": "http://json.schemastore.org/json-patch"
+ },
+ {
+ "name": "jsconfig.json",
+ "description": "JavaScript project configuration file",
+ "fileMatch": [ "jsconfig.json" ],
+ "url": "http://json.schemastore.org/jsconfig"
+ },
+ {
+ "name": "launchsettings.json",
+ "description": "A JSON schema for the ASP.NET LaunchSettings.json files",
+ "fileMatch": [ "launchsettings.json" ],
+ "url": "http://json.schemastore.org/launchsettings"
+ },
+ {
+ "name": "Microsoft Band Web Tile",
+ "description": "Microsoft Band Web Tile manifest file",
+ "url": "http://json.schemastore.org/band-manifest"
+ },
+ {
+ "name": ".modernizrrc",
+ "description": "Webpack modernizr-loader configuration file",
+ "fileMatch": [ ".modernizrrc" ],
+ "url": "http://json.schemastore.org/modernizrrc"
+ },
+ {
+ "name": "mycode.json",
+ "description": "JSON schema for mycode.js files",
+ "fileMatch": [ "mycode.json" ],
+ "url": "http://json.schemastore.org/mycode"
+ },
+ {
+ "name": "news in JSON",
+ "description": "A JSON Schema for ninjs by the IPTC. News and publishing information. See http://dev.iptc.org/ninjs",
+ "fileMatch": [ "ninjs.json" ],
+ "url": "http://json.schemastore.org/ninjs"
+ },
+ {
+ "name": "nuget-project.json",
+ "description": "JSON schema for NuGet project.json files.",
+ "url": "http://json.schemastore.org/nuget-project",
+ "versions": {
+ "3.3.0": "http://json.schemastore.org/nuget-project-3.3.0"
+ }
+ },
+ {
+ "name": "package.json",
+ "description": "NPM configuration file",
+ "fileMatch": [ "package.json" ],
+ "url": "http://json.schemastore.org/package"
+ },
+ {
+ "name": "package.manifest",
+ "description": "Umbraco package configuration file",
+ "fileMatch": [ "package.manifest" ],
+ "url": "http://json.schemastore.org/package.manifest"
+ },
+ {
+ "name": "pattern.json",
+ "description": "Patternplate pattern manifest file",
+ "fileMatch": [ "pattern.json" ],
+ "url": "http://json.schemastore.org/pattern"
+ },
+ {
+ "name": "project.json",
+ "description": "ASP.NET vNext project configuration file",
+ "fileMatch": [ "project.json" ],
+ "url": "http://json.schemastore.org/project",
+ "versions": {
+ "1.0.0-beta3": "http://json.schemastore.org/project-1.0.0-beta3",
+ "1.0.0-beta4": "http://json.schemastore.org/project-1.0.0-beta4",
+ "1.0.0-beta5": "http://json.schemastore.org/project-1.0.0-beta5",
+ "1.0.0-beta6": "http://json.schemastore.org/project-1.0.0-beta6",
+ "1.0.0-beta8": "http://json.schemastore.org/project-1.0.0-beta8",
+ "1.0.0-rc1": "http://json.schemastore.org/project-1.0.0-rc1",
+ "1.0.0-rc1-update1": "http://json.schemastore.org/project-1.0.0-rc1",
+ "1.0.0-rc2": "http://json.schemastore.org/project-1.0.0-rc2"
+ }
+ },
+ {
+ "name": "project-1.0.0-beta3.json",
+ "description": "ASP.NET vNext project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-beta3"
+ },
+ {
+ "name": "project-1.0.0-beta4.json",
+ "description": "ASP.NET vNext project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-beta4"
+ },
+ {
+ "name": "project-1.0.0-beta5.json",
+ "description": "ASP.NET vNext project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-beta5"
+ },
+ {
+ "name": "project-1.0.0-beta6.json",
+ "description": "ASP.NET vNext project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-beta6"
+ },
+ {
+ "name": "project-1.0.0-beta8.json",
+ "description": "ASP.NET vNext project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-beta8"
+ },
+ {
+ "name": "project-1.0.0-rc1.json",
+ "description": "ASP.NET vNext project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-rc1"
+ },
+ {
+ "name": "project-1.0.0-rc2.json",
+ "description": ".NET Core project configuration file",
+ "url": "http://json.schemastore.org/project-1.0.0-rc2"
+ },
+ {
+ "name": "*.resjson",
+ "description": "Windows App localization file",
+ "fileMatch": [ "*.resjson" ],
+ "url": "http://json.schemastore.org/resjson"
+ },
+ {
+ "name": "JSON Resume",
+ "description": "A JSON format to describe resumes",
+ "fileMatch": [ "resume.json" ],
+ "url": "http://json.schemastore.org/resume"
+ },
+ {
+ "name": "sarif-1.0.0.json",
+ "description": "Static Analysis Results Interchange Format (SARIF)",
+ "fileMatch": [ "*.sarif,*.sarif.json" ],
+ "url": "http://json.schemastore.org/sarif",
+ "versions": {
+ "1.0.0-beta.4": "http://json.schemastore.org/sarif-1.0.0-beta.4.json",
+ "1.0.0-beta.5": "http://json.schemastore.org/sarif-1.0.0-beta.5.json",
+ "1.0.0": "http://json.schemastore.org/sarif-1.0.0"
+ }
+ },
+ {
+ "name": "sarif-1.0.0.json",
+ "description": "Static Analysis Results Interchange Format (SARIF)",
+ "url": "http://json.schemastore.org/sarif-1.0.0.json"
+ },
+ {
+ "name": "sarif-1.0.0-beta.5.json",
+ "description": "Static Analysis Results Interchange Format (SARIF)",
+ "url": "http://json.schemastore.org/sarif-1.0.0-beta.5.json"
+ },
+ {
+ "name": "sarif-1.0.0-beta.4.json",
+ "description": "Static Analysis Results Interchange Format (SARIF)",
+ "url": "http://json.schemastore.org/sarif-1.0.0-beta.4.json"
+ },
+ {
+ "name": "Schema Catalog",
+ "description": "JSON Schema catalog files compatible with SchemaStore.org",
+ "url": "http://json.schemastore.org/schema-catalog"
+ },
+ {
+ "name": "settings.job",
+ "description": "Azure Webjob settings file",
+ "fileMatch": [ "settings.job" ],
+ "url": "http://json.schemastore.org/settings.job"
+ },
+ {
+ "name": "Source Maps v3",
+ "description": "Source Map files version 3",
+ "fileMatch": [ "*.map" ],
+ "url": "http://json.schemastore.org/sourcemap-v3"
+ },
+ {
+ "name": ".sprite files",
+ "description": "Schema for image sprite generation files",
+ "fileMatch": [ "*.sprite" ],
+ "url": "http://json.schemastore.org/sprite"
+ },
+ {
+ "name": "StyleCop Analyzers Configuration",
+ "description": "Configuration file for StyleCop Analyzers",
+ "fileMatch": [ "stylecop.json" ],
+ "url": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json"
+ },
+ {
+ "name": "Swagger API 2.0",
+ "description": "Swagger API 2.0 schema",
+ "url": "http://json.schemastore.org/swagger-2.0"
+ },
+
+ {
+ "name": "templatsources.json",
+ "description": "SideWaffle template source schema",
+ "fileMatch": [ "templatesources.json" ],
+ "url": "http://json.schemastore.org/templatesources"
+ },
+ {
+ "name": "tsconfig.json",
+ "description": "TypeScript compiler configuration file",
+ "fileMatch": [ "tsconfig.json" ],
+ "url": "http://json.schemastore.org/tsconfig"
+ },
+ {
+ "name": "tsd.json",
+ "description": "JSON schema for DefinatelyTyped description manager (TSD)",
+ "fileMatch": [ "tsd.json" ],
+ "url": "http://json.schemastore.org/tsd"
+ },
+ {
+ "name": "tsdrc.json",
+ "description": "TypeScript Definition manager (tsd) global settings file",
+ "fileMatch": [ ".tsdrc" ],
+ "url": "http://json.schemastore.org/tsdrc"
+ },
+ {
+ "name": "tslint.json",
+ "description": "TypeScript Lint configuration file",
+ "fileMatch": [ "tslint.json" ],
+ "url": "http://json.schemastore.org/tslint"
+ },
+ {
+ "name": "typings.json",
+ "description": "Typings TypeScript definitions manager definition file",
+ "fileMatch": [ "typings.json" ],
+ "url": "http://json.schemastore.org/typings"
+ },
+ {
+ "name": "typingsrc.json",
+ "description": "Typings TypeScript definitions manager configuration file",
+ "fileMatch": [ ".typingsrc" ],
+ "url": "http://json.schemastore.org/typingsrc"
+ },
+ {
+ "name": "vega.json",
+ "description": "Vega visualization specification file",
+ "fileMatch": [ "*.vg", "*.vg.json" ],
+ "url": "http://json.schemastore.org/vega"
+ },
+ {
+ "name": "vega-lite.json",
+ "description": "Vega-Lite visualization specification file",
+ "fileMatch": [ "*.vl", "*.vl.json" ],
+ "url": "http://json.schemastore.org/vega-lite"
+ },
+ {
+ "name": "version.json",
+ "description": "A project version descriptor file used by Nerdbank.GitVersioning",
+ "fileMatch": [ "version.json" ],
+ "url": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json"
+ },
+ {
+ "name": "Web Manifest",
+ "description": "Web Appliation manifest file",
+ "fileMatch": [ "manifest.json" ],
+ "url": "http://json.schemastore.org/web-manifest"
+ },
+ {
+ "name": "webjobs-list.json",
+ "description": "Azure Webjob list file",
+ "fileMatch": [ "webjobs-list.json" ],
+ "url": "http://json.schemastore.org/webjobs-list"
+ },
+ {
+ "name": "webjobpublishsettings.json",
+ "description": "Azure Webjobs publish settings file",
+ "fileMatch": [ "webjobpublishsettings.json" ],
+ "url": "http://json.schemastore.org/webjob-publish-settings"
+ },
+ {
+ "name": "JSON-stat 2.0",
+ "description": "JSON-stat 2.0 Schema",
+ "url": "https://json-stat.org/format/schema/2.0/"
+ },
+ {
+ "name": "KSP-CKAN 1.16",
+ "description": "Metadata spec v1.16 for KSP-CKAN",
+ "fileMatch": [ "*.ckan" ],
+ "url": "http://json.schemastore.org/ksp-ckan-1.16"
+ },
+ {
+ "name": "JSON Schema Draft 4",
+ "description": "Meta-validation schema for JSON Schema Draft 4",
+ "url": "http://json-schema.org/draft-04/schema"
+ }
+ ]
+}
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/download/HttpClientProvider.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/download/HttpClientProvider.java
new file mode 100644
index 0000000000..f84426885f
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/download/HttpClientProvider.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.wst.json.core.internal.download;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Date;
+
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.config.RequestConfig.Builder;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.eclipse.core.net.proxy.IProxyData;
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.json.internal.JSONPlugin;
+import org.eclipse.wst.json.core.JSONCorePlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class HttpClientProvider {
+
+ private static final String JSON_DOWNLOAD_FOLDER = ".jsonDownloadFolder"; //$NON-NLS-1$
+ public static final String PROTOCOL_FILE = "file"; //$NON-NLS-1$
+ public static final String PROTOCOL_PLATFORM = "platform"; //$NON-NLS-1$
+
+ public static File getFile(URL url) throws IOException {
+ if (url == null) {
+ return null;
+ }
+ if (PROTOCOL_FILE.equals(url.getProtocol())
+ || PROTOCOL_PLATFORM.equalsIgnoreCase(url.getProtocol())) {
+ File file;
+ try {
+ file = new File(new URI(url.toExternalForm()));
+ } catch (Exception e) {
+ file = new File(url.getFile());
+ }
+ if (!file.exists()) {
+ return null;
+ }
+ return file;
+ }
+ File file = getCachedFile(url);
+ long urlLastModified = getLastModified(url);
+ if (file.exists()) {
+ long lastModified = file.lastModified();
+ if (urlLastModified > lastModified) {
+ file = download(file, url);
+ file.setLastModified(urlLastModified);
+ }
+ } else {
+ file = download(file, url);
+ if (urlLastModified > -1) {
+ file.setLastModified(urlLastModified);
+ }
+ }
+ return file;
+ }
+
+ private static File download(File file, URL url) {
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+ CloseableHttpResponse response = null;
+ OutputStream out = null;
+ file.getParentFile().mkdirs();
+ try {
+ HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
+ Builder builder = RequestConfig.custom();
+ HttpHost proxy = getProxy(target);
+ if (proxy != null) {
+ builder = builder.setProxy(proxy);
+ }
+ RequestConfig config = builder.build();
+ HttpGet request = new HttpGet(url.toURI());
+ request.setConfig(config);
+ response = httpclient.execute(target, request);
+ InputStream in = response.getEntity().getContent();
+ out = new BufferedOutputStream(new FileOutputStream(file));
+ copy(in, out);
+ return file;
+ } catch (Exception e) {
+ logWarning(e);
+ ;
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ }
+ }
+ if (response != null) {
+ try {
+ response.close();
+ } catch (IOException e) {
+ }
+ }
+ try {
+ httpclient.close();
+ } catch (IOException e) {
+ }
+ }
+ return null;
+ }
+
+ private static void copy(InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[8192];
+ int n = 0;
+ while ((n = in.read(buffer)) != -1) {
+ out.write(buffer, 0, n);
+ }
+ }
+
+ private static long getLastModified(URL url) {
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+ CloseableHttpResponse response = null;
+ try {
+ HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
+ Builder builder = RequestConfig.custom();
+ HttpHost proxy = getProxy(target);
+ if (proxy != null) {
+ builder = builder.setProxy(proxy);
+ }
+ RequestConfig config = builder.build();
+ HttpHead request = new HttpHead(url.toURI());
+ request.setConfig(config);
+ response = httpclient.execute(target, request);
+ Header[] s = response.getHeaders("last-modified");
+ if (s != null && s.length > 0) {
+ String lastModified = s[0].getValue();
+ return new Date(lastModified).getTime();
+ }
+ } catch (Exception e) {
+ logWarning(e);
+ return -1;
+ } finally {
+ if (response != null) {
+ try {
+ response.close();
+ } catch (IOException e) {
+ }
+ }
+ try {
+ httpclient.close();
+ } catch (IOException e) {
+ }
+ }
+ return -1;
+ }
+
+ private static HttpHost getProxy(HttpHost target) {
+ final IProxyService proxyService = getProxyService();
+ IProxyData[] select = null;
+ try {
+ select = proxyService.select(new URI(target.toURI()));
+ } catch (URISyntaxException e) {
+ logWarning(e);
+ return null;
+ }
+ String type = target.getSchemeName();
+ for (IProxyData proxyData : select) {
+ if (proxyData.getType().equals(type)) {
+ return new HttpHost(proxyData.getHost(), proxyData.getPort());
+ }
+ }
+ return null;
+ }
+
+ private static void logWarning(Exception e) {
+ IStatus status = new Status(IStatus.WARNING, JSONCorePlugin.PLUGIN_ID, e.getMessage(), e);
+ JSONCorePlugin.getDefault().getLog().log(status);
+ }
+
+ public static IProxyService getProxyService() {
+ BundleContext bc = JSONPlugin.getDefault().getBundle().getBundleContext();
+ ServiceReference<?> serviceReference = bc.getServiceReference(IProxyService.class.getName());
+ IProxyService service = (IProxyService) bc.getService(serviceReference);
+ return service;
+ }
+
+ private static File getCachedFile(URL url) {
+ IPath stateLocation = JSONCorePlugin.getDefault().getStateLocation();
+ IPath downloadFolder = stateLocation.append(JSON_DOWNLOAD_FOLDER);
+ String urlPath = url.getPath();
+ IPath filePath = downloadFolder.append(urlPath);
+ File file = filePath.toFile();
+ return file;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/Catalog.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/Catalog.java
index 16acdcd0d0..e7cc896ad9 100644
--- a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/Catalog.java
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/Catalog.java
@@ -11,7 +11,6 @@
package org.eclipse.wst.json.core.internal.schema.catalog;
import java.io.IOException;
-import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -287,6 +286,7 @@ public class Catalog implements ICatalog {
public void load() {
new CatalogContributorRegistryReader(Catalog.this).readRegistry();
+ new CatalogSchemastoreReader(Catalog.this).readSchemastore();
/*
* Here we save the file in order to 'reflect' the catalog that
* we've created from plugin extensions to disk. The 'system'
@@ -298,34 +298,9 @@ public class Catalog implements ICatalog {
class UserCatalogLS extends CatalogLS {
public void load() {
- InputStream inputStream = null;
- try {
- if (location != null && location.length() > 0) {
- URL url = new URL(location);
- inputStream = url.openStream();
- boolean oldNotificationEnabled = isNotificationEnabled();
- setNotificationEnabled(false);
- clear();
- try {
- // CatalogReader.read(Catalog.this, inputStream);
- } finally {
- setNotificationEnabled(oldNotificationEnabled);
- }
- } else {
- clear();
- }
- notifyChanged();
- } catch (Exception e) {
- // This is OK since the catalog may not exist before we create
- // it
- } finally {
- if (inputStream != null) {
- try {
- inputStream.close();
- } catch (Exception e) {
- }
- }
- }
+ new CatalogUserCatalogReader(Catalog.this).readCatalog();
+
+ save();
}
}
@@ -369,7 +344,11 @@ public class Catalog implements ICatalog {
public void addCatalogElement(ICatalogElement element) {
synchronized (catalogElements) {
- catalogElements.add(element);
+ if (!catalogElements.contains(element)) {
+ catalogElements.add(element);
+ } else {
+ return;
+ }
}
element.setOwnerCatalog(this);
internalResolver = null;
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogElement.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogElement.java
index 9f19681e92..73598b2ed7 100644
--- a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogElement.java
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogElement.java
@@ -146,4 +146,29 @@ public class CatalogElement implements ICatalogElement {
return element;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ CatalogElement other = (CatalogElement) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
}
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogSchemastoreReader.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogSchemastoreReader.java
new file mode 100644
index 0000000000..5a323d7c8d
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogSchemastoreReader.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.wst.json.core.internal.schema.catalog;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.json.provisonnal.com.eclipsesource.json.JsonArray;
+import org.eclipse.json.provisonnal.com.eclipsesource.json.JsonObject;
+import org.eclipse.json.provisonnal.com.eclipsesource.json.JsonValue;
+import org.eclipse.wst.json.core.JSONCorePlugin;
+import org.eclipse.wst.json.core.internal.Logger;
+import org.eclipse.wst.json.core.internal.download.HttpClientProvider;
+import org.eclipse.wst.json.core.schema.catalog.ICatalog;
+import org.eclipse.wst.json.core.schema.catalog.ICatalogElement;
+import org.eclipse.wst.json.core.schema.catalog.ICatalogEntry;
+import org.osgi.framework.Bundle;
+
+public class CatalogSchemastoreReader {
+
+ private static final String SCHEMAS = "schemas"; //$NON-NLS-1$
+ private static final String SCHEMASTORE_CATALOG = "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/api/json/catalog.json"; //$NON-NLS-1$
+ protected ICatalog catalog;
+
+ protected CatalogSchemastoreReader(ICatalog catalog) {
+ this.catalog = catalog;
+ }
+
+ protected void readSchemastore() {
+ File f = getUrl();
+ if (f != null) {
+ int type = ICatalogEntry.ENTRY_TYPE_SCHEMA;
+ JsonValue schemas;
+ try {
+ InputStreamReader reader = new InputStreamReader(new FileInputStream(f));
+ JsonObject json = JsonObject.readFrom(reader);
+ schemas = json.get(SCHEMAS);
+ } catch (IOException e) {
+ Logger.logException(e);
+ return;
+ }
+ if (schemas != null && schemas instanceof JsonArray) {
+ JsonArray elements = (JsonArray) schemas;
+ Iterator<JsonValue> iter = elements.iterator();
+ while (iter.hasNext()) {
+ JsonValue value = iter.next();
+ if (value instanceof JsonObject) {
+ JsonObject jsonObject = (JsonObject) value;
+ JsonValue urlJson = jsonObject.get("url"); //$NON-NLS-1$
+ JsonValue fileMatchJson = jsonObject.get("fileMatch"); //$NON-NLS-1$
+ if (urlJson != null && fileMatchJson != null && urlJson.isString() && fileMatchJson.isArray()) {
+ String url = urlJson.asString();
+ JsonArray fileMatchArray = fileMatchJson.asArray();
+ Iterator<JsonValue> fileIter = fileMatchArray.iterator();
+ while (fileIter.hasNext()) {
+ JsonValue fileMatchValue = fileIter.next();
+ if (fileMatchValue.isString()) {
+ String fileMatch = fileMatchValue.asString();
+ ICatalogElement catalogElement = catalog.createCatalogElement(type);
+ if (catalogElement instanceof ICatalogEntry) {
+ ICatalogEntry entry = (ICatalogEntry) catalogElement;
+ entry.setKey(fileMatch);
+ entry.setURI(url);
+ entry.setId(fileMatch);
+ }
+ catalog.addCatalogElement(catalogElement);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static File getUrl() {
+ try {
+ File f = HttpClientProvider.getFile(new URL(SCHEMASTORE_CATALOG));
+ if (f == null || !f.exists()) {
+ URL url = getUrlFromBundle();
+ File file;
+ try {
+ file = new File(url.toURI());
+ } catch(URISyntaxException e) {
+ file = new File(url.getPath());
+ }
+ return file;
+ } else {
+ return f;
+ }
+ } catch (Exception e) {
+ Logger.logException(e);
+ }
+ return null;
+ }
+
+ private static URL getUrlFromBundle() {
+ Bundle bundle = Platform.getBundle(JSONCorePlugin.PLUGIN_ID);
+ if (bundle != null) {
+ URL[] urls = FileLocator.findEntries(bundle, new Path("/schemastore/catalog.json")); //$NON-NLS-1$
+ if (urls != null && urls.length > 0) {
+ try {
+ return FileLocator.resolve(urls[0]);
+ } catch (IOException e) {
+ Logger.logException(e);
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogUserCatalogReader.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogUserCatalogReader.java
new file mode 100644
index 0000000000..0ca05c1e54
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/CatalogUserCatalogReader.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.wst.json.core.internal.schema.catalog;
+
+import java.util.Set;
+
+import org.eclipse.wst.json.core.schema.catalog.ICatalog;
+import org.eclipse.wst.json.core.schema.catalog.ICatalogElement;
+import org.eclipse.wst.json.core.schema.catalog.ICatalogEntry;
+
+public class CatalogUserCatalogReader {
+
+ protected ICatalog catalog;
+
+ protected CatalogUserCatalogReader(ICatalog catalog) {
+ this.catalog = catalog;
+ }
+
+ protected void readCatalog() {
+ int type = ICatalogEntry.ENTRY_TYPE_SCHEMA;
+ Set<UserEntry> entries = EntryParser.getUserEntries();
+ for (UserEntry ue : entries) {
+ ICatalogElement catalogElement = catalog.createCatalogElement(type);
+ if (catalogElement instanceof ICatalogEntry) {
+ ICatalogEntry entry = (ICatalogEntry) catalogElement;
+ entry.setKey(ue.getFileMatch());
+ entry.setURI(ue.getUrl().toString());
+ entry.setId(ue.getFileMatch());
+ }
+ catalog.addCatalogElement(catalogElement);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/EntryParser.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/EntryParser.java
new file mode 100644
index 0000000000..acb659aae8
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/EntryParser.java
@@ -0,0 +1,138 @@
+/*************************************************************************************
+ * Copyright (c) 2014-2015 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * JBoss by Red Hat - Initial implementation.
+ ************************************************************************************/
+package org.eclipse.wst.json.core.internal.schema.catalog;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.wst.json.core.JSONCorePlugin;
+
+@SuppressWarnings("nls")
+public class EntryParser {
+
+ public static final String JSON_CATALOG_ENTRIES = "catalogEntries"; //$NON-NLS-1$
+ private static final JAXBContext jaxbContext;
+
+ static {
+ try {
+ jaxbContext = JAXBContext.newInstance(EntriesWrapper.class);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Set<UserEntry> parse(String xml) throws CoreException {
+ if (xml == null || xml.trim().isEmpty()) {
+ return null;
+ }
+ try {
+ EntriesWrapper list = (EntriesWrapper) unmarshall(jaxbContext, xml);
+ return list.entries == null ? Collections.<UserEntry>emptySet() : list.entries;
+ } catch (Exception e) {
+ throw new CoreException(new Status(IStatus.ERROR, JSONCorePlugin.PLUGIN_ID,
+ "Unable to parse entry", e));
+ }
+ }
+
+ public String serialize(Set<UserEntry> entries) throws CoreException {
+ try {
+ EntriesWrapper list = new EntriesWrapper();
+ list.entries = entries;
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(list, writer);
+ return writer.toString();
+ } catch (Exception shouldntHappen) {
+ throw new CoreException(new Status(IStatus.ERROR, JSONCorePlugin.PLUGIN_ID,
+ "Unable to serialize entries ", shouldntHappen));
+ }
+ }
+
+ public static Set<UserEntry> getUserEntries() {
+ Set<UserEntry> entries = new LinkedHashSet<UserEntry>();
+ IEclipsePreferences prefs = getPreferences();
+ String xml = prefs.get(JSON_CATALOG_ENTRIES, null);
+ if (xml != null && !xml.trim().isEmpty()) {
+ try {
+ Set<UserEntry> set = new EntryParser().parse(xml);
+ if (set != null) {
+ entries.addAll(set);
+ }
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, JSONCorePlugin.PLUGIN_ID, e
+ .getLocalizedMessage(), e);
+ JSONCorePlugin.getDefault().getLog().log(status);
+ }
+ }
+ return entries;
+ }
+
+ private static IEclipsePreferences getPreferences() {
+ IEclipsePreferences preferences = InstanceScope.INSTANCE
+ .getNode("org.eclipse.wst.json.ui"); //$NON-NLS-1$
+ return preferences;
+ }
+
+ @XmlRootElement(name = "entries")
+ @XmlAccessorType (XmlAccessType.FIELD)
+ static class EntriesWrapper {
+ @XmlElement(name = "entry", type=UserEntry.class)
+ Set<UserEntry> entries;
+ }
+
+ protected Object unmarshall(JAXBContext jaxbContext, String xml) throws JAXBException, IOException, XMLStreamException {
+ return unmarshall(jaxbContext, new StringReader(xml));
+ }
+
+ protected Object unmarshall(JAXBContext jaxbContext, File file) throws JAXBException, IOException, XMLStreamException {
+ return unmarshall(jaxbContext, new FileReader(file));
+ }
+
+ protected Object unmarshall(JAXBContext jaxbContext, Reader reader) throws JAXBException, IOException, XMLStreamException {
+ Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
+ XMLInputFactory xmlif = XMLInputFactory.newInstance();
+ Reader r = null;
+ try {
+ r = reader;
+ XMLStreamReader xmler = xmlif.createXMLStreamReader(r);
+ return jaxbUnmarshaller.unmarshal(xmler);
+ } finally {
+ if (r != null) {
+ r.close();
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntries.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntries.java
new file mode 100644
index 0000000000..23b296850f
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntries.java
@@ -0,0 +1,26 @@
+/*************************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * JBoss by Red Hat - Initial implementation.
+ ************************************************************************************/
+package org.eclipse.wst.json.core.internal.schema.catalog;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class UserEntries {
+ private Set<UserEntry> entries = new HashSet<UserEntry>();
+
+ public Set<UserEntry> getEntries() {
+ return entries;
+ }
+
+ public void add(UserEntry entry) {
+ entries.add(entry);
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntry.java b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntry.java
new file mode 100644
index 0000000000..512fa9cbbc
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.core/src/org/eclipse/wst/json/core/internal/schema/catalog/UserEntry.java
@@ -0,0 +1,45 @@
+/*************************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * JBoss by Red Hat - Initial implementation.
+ ************************************************************************************/
+package org.eclipse.wst.json.core.internal.schema.catalog;
+
+import java.net.URI;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlAccessorType (XmlAccessType.FIELD)
+@XmlRootElement(name="entry")
+public class UserEntry {
+
+ @XmlAttribute
+ private String fileMatch;
+
+ @XmlAttribute
+ private URI url;
+
+ public String getFileMatch() {
+ return fileMatch;
+ }
+
+ public void setFileMatch(String fileMatch) {
+ this.fileMatch = fileMatch;
+ }
+
+ public URI getUrl() {
+ return url;
+ }
+
+ public void setUrl(URI url) {
+ this.url = url;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.json.schemaprocessor/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.json.schemaprocessor/META-INF/MANIFEST.MF
index b534b58a7a..1f92e91161 100644
--- a/bundles/org.eclipse.wst.json.schemaprocessor/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.json.schemaprocessor/META-INF/MANIFEST.MF
@@ -15,4 +15,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.json
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.wst.json.schemaprocessor,
+ org.eclipse.wst.json.schemaprocessor.internal
diff --git a/bundles/org.eclipse.wst.json.schemaprocessor/src/org/eclipse/wst/json/schemaprocessor/internal/JSONSchemaProcessor.java b/bundles/org.eclipse.wst.json.schemaprocessor/src/org/eclipse/wst/json/schemaprocessor/internal/JSONSchemaProcessor.java
index d330918278..f5eda6c734 100644
--- a/bundles/org.eclipse.wst.json.schemaprocessor/src/org/eclipse/wst/json/schemaprocessor/internal/JSONSchemaProcessor.java
+++ b/bundles/org.eclipse.wst.json.schemaprocessor/src/org/eclipse/wst/json/schemaprocessor/internal/JSONSchemaProcessor.java
@@ -10,27 +10,43 @@
*/
package org.eclipse.wst.json.schemaprocessor.internal;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
import org.eclipse.json.impl.schema.JSONSchemaDocument;
import org.eclipse.json.schema.IJSONSchemaDocument;
import org.eclipse.json.schema.IJSONSchemaProcessor;
-import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
+import org.eclipse.wst.json.core.internal.download.HttpClientProvider;
public class JSONSchemaProcessor implements IJSONSchemaProcessor {
+ private static final int MAP_SIZE = 10;
+ private static Map<String,IJSONSchemaDocument> schemaDocuments = new LinkedHashMap<String, IJSONSchemaDocument>();
+
@Override
public IJSONSchemaDocument getSchema(String uriString) throws IOException {
- String physicalLocation = URIResolverPlugin.createResolver()
- .resolvePhysicalLocation("", "", uriString);
- URL url = new URL(physicalLocation);
- return new JSONSchemaDocument(new InputStreamReader(url.openStream()));
+ IJSONSchemaDocument schemaDocument = schemaDocuments.get(uriString);
+ if (schemaDocument != null) {
+ return schemaDocument;
+ }
+ int size = schemaDocuments.size();
+ if (size > MAP_SIZE) {
+ String key = schemaDocuments.keySet().iterator().next();
+ schemaDocuments.remove(key);
+ }
+ File f = HttpClientProvider.getFile(new URL(uriString));
+ schemaDocument = new JSONSchemaDocument(new InputStreamReader(new FileInputStream(f)));
+ schemaDocuments.put(uriString, schemaDocument);
+ return schemaDocument;
}
- // @Override
- // public IJSONProperty findProperty(IJSONPath path, IJSONSchema schema) {
- // // TODO Auto-generated method stub
- // return null;
- // }
+
+ public static void clearCache() {
+ schemaDocuments.clear();
+ }
+
}
diff --git a/bundles/org.eclipse.wst.json.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.json.ui/META-INF/MANIFEST.MF
index dfce495a5a..ff37b5ef6f 100644
--- a/bundles/org.eclipse.wst.json.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.json.ui/META-INF/MANIFEST.MF
@@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.wst.json.core,
org.eclipse.wst.validation,
org.eclipse.ui.workbench.texteditor,
- org.eclipse.json
+ org.eclipse.json,
+ org.eclipse.wst.json.schemaprocessor;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.wst.json.ui,
diff --git a/bundles/org.eclipse.wst.json.ui/icons/WizBan.png b/bundles/org.eclipse.wst.json.ui/icons/WizBan.png
new file mode 100644
index 0000000000..1173df9a4c
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.ui/icons/WizBan.png
Binary files differ
diff --git a/bundles/org.eclipse.wst.json.ui/plugin.properties b/bundles/org.eclipse.wst.json.ui/plugin.properties
index 22cb8113f9..8094e8c35a 100644
--- a/bundles/org.eclipse.wst.json.ui/plugin.properties
+++ b/bundles/org.eclipse.wst.json.ui/plugin.properties
@@ -26,6 +26,7 @@ JSON_Source.name=Editor
JSON_Content_Assist.name=Content Assist
JSON_Validator.name=Validation
JSON_Templates.name=Templates
+_UI_PREF_JSON_CATALOG=JSON Catalog
JSON_Styles.name=Styles
JSON_Syntax_Coloring=Syntax Coloring
JSON_Typing=Typing
@@ -41,3 +42,5 @@ proposalCategory.jsonTemplates=JSON Template Proposals
All_JSON_context_type_Extension_Element.name=All JSON
JSON_New_context_type_Extension_Element.name=New JSON
JSON_Package_context_type_Extension_Element.name=New package.json
+
+preferenceKeywords.jsoncatalog=JSON Catalog
diff --git a/bundles/org.eclipse.wst.json.ui/plugin.xml b/bundles/org.eclipse.wst.json.ui/plugin.xml
index d59992a960..a1c188a62e 100644
--- a/bundles/org.eclipse.wst.json.ui/plugin.xml
+++ b/bundles/org.eclipse.wst.json.ui/plugin.xml
@@ -133,13 +133,14 @@
id="org.eclipse.wst.sse.ui.preferences.json.colors">
<keywordReference id="org.eclipse.wst.json.ui.styles"/>
</page>
- <!--<page
+ <page
name="%_UI_PREF_JSON_CATALOG"
category="org.eclipse.wst.json.ui.preferences.json"
- class="org.eclipse.wst.json.ui.internal.catalog.JSONCatalogPreferencePage"
- id="org.eclipse.wst.json.core.ui.JSONCatalogPreferencePage">
- <keywordReference id="org.eclipse.wst.json.ui.jsoncatalog"/>
+ class="org.eclipse.wst.json.ui.internal.preferences.JSONCatalogPreferencePage"
+ id="org.eclipse.wst.json.ui.internal.preferences.JSONCatalogPreferencePage">
+ <keywordReference id="org.eclipse.wst.json.ui.jsoncatalog"/>
</page>
+ <!--
<page
name="%JSON_Typing"
category="org.eclipse.wst.sse.ui.preferences.json.source"
@@ -187,6 +188,9 @@
<keyword
label="%preferenceKeywords.webcontent"
id="org.eclipse.wst.json.ui.webcontent"/>
+ <keyword
+ label="%preferenceKeywords.jsoncatalog"
+ id="org.eclipse.wst.json.ui.jsoncatalog"/>
<keyword
id="org.eclipse.wst.json.ui.contentassist"
label="%preferenceKeywords.contentassist">
diff --git a/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.java b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.java
index 48f22ab811..c8ab168ee7 100644
--- a/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.java
+++ b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.java
@@ -23,6 +23,20 @@ public class JSONUIMessages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.wst.json.ui.internal.JSONUIMessages";//$NON-NLS-1$
+ public static String Invalid_URL;
+ public static String The_name_field_is_required;
+ public static String The_entry_already_exists;
+ public static String The_url_field_is_required;
+ public static String Browse;
+ public static String URL;
+ public static String FileMatch;
+ public static String Add_Catalog_Entry;
+ public static String Edit_Catalog_Entry;
+ public static String Remove;
+ public static String Edit;
+ public static String Add;
+ public static String JSON_Catalog_Entries;
+
private static ResourceBundle fResourceBundle;
// Validation
diff --git a/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.properties b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.properties
index 28ad11ad37..f6ca05f6d3 100644
--- a/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.properties
+++ b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/JSONUIMessages.properties
@@ -79,3 +79,18 @@ PrefsLabel_SelectorWhitespace=Inser&t whitespace between selectors
## JSON Preferences -- source ##
PrefsLabel_WrappingWithoutAttr=Disable wrapping in style &attribute of HTML
PrefsLabel_WrappingInsertLineBreak=Insert &line break between properties
+
+JSON_Catalog_Entries=JSON Catalog Entries
+Add=Add
+Edit=Edit
+Remove=Remove
+Add_Catalog_Entry=Add Catalog Entry
+Edit_Catalog_Entry=Edit Catalog Entry
+FileMatch=File Match:
+URL=URL:
+Browse=Browse...
+The_name_field_is_required=The name field is required.
+The_entry_already_exists=The entry already exists.
+The_url_field_is_required=The url field is required.
+Invalid_URL=Invalid url.
+
diff --git a/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/EntryDialog.java b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/EntryDialog.java
new file mode 100644
index 0000000000..beba9e746b
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/EntryDialog.java
@@ -0,0 +1,213 @@
+/*************************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * JBoss by Red Hat - Initial implementation.
+ ************************************************************************************/
+package org.eclipse.wst.json.ui.internal.preferences;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Set;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.json.core.internal.schema.catalog.UserEntries;
+import org.eclipse.wst.json.core.internal.schema.catalog.UserEntry;
+import org.eclipse.wst.json.ui.internal.JSONUIMessages;
+import org.eclipse.wst.json.ui.internal.JSONUIPlugin;
+
+public class EntryDialog extends TitleAreaDialog {
+
+ private Image dlgTitleImage;
+ private UserEntry selectedEntry;
+ private String fileMatch;
+ private URI url;
+ private Text fileMatchText;
+ private Text urlText;
+ private Button okButton;
+ private UserEntries entries;
+
+ protected EntryDialog(Shell parentShell, UserEntry entry, UserEntries entries) {
+ super(parentShell);
+ this.selectedEntry = entry;
+ this.entries = entries;
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+
+ Control contents = super.createContents(parent);
+ if (selectedEntry == null) {
+ setTitle(JSONUIMessages.Add_Catalog_Entry);
+ setMessage(JSONUIMessages.Add_Catalog_Entry);
+ } else {
+ setTitle(JSONUIMessages.Edit_Catalog_Entry);
+ setMessage(JSONUIMessages.Edit_Catalog_Entry);
+ }
+ ImageDescriptor descriptor = JSONUIPlugin
+ .imageDescriptorFromPlugin(JSONUIPlugin.PLUGIN_ID,
+ "icons/WizBan.png"); //$NON-NLS-1$
+ if(descriptor != null) {
+ dlgTitleImage = descriptor.createImage();
+ setTitleImage(dlgTitleImage);
+ }
+
+ return contents;
+ }
+
+ @Override
+ public boolean close() {
+ if (dlgTitleImage != null) {
+ dlgTitleImage.dispose();
+ }
+ return super.close();
+ }
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite parentComposite = (Composite) super.createDialogArea(parent);
+
+ Composite container = new Composite(parentComposite, SWT.FILL);
+ GridLayout layout = new GridLayout(3,false);
+ layout.marginWidth = layout.marginHeight = 10;
+ container.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ container.setLayoutData(gd);
+
+ Label nameLabel = new Label(container, SWT.NONE);
+ nameLabel.setText(JSONUIMessages.FileMatch);
+ fileMatchText = new Text(container, SWT.SINGLE|SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan=2;
+ fileMatchText.setLayoutData(gd);
+ fileMatchText.addModifyListener(new ModifyListener(){
+
+ public void modifyText(ModifyEvent e) {
+ validatePage();
+ }
+ });
+
+ Label urlLabel = new Label(container, SWT.NONE);
+ urlLabel.setText(JSONUIMessages.URL);
+ urlText = new Text(container, SWT.SINGLE|SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ urlText.setLayoutData(gd);
+ urlText.addModifyListener(new ModifyListener(){
+
+ public void modifyText(ModifyEvent e) {
+ validatePage();
+ }
+
+ });
+ if (selectedEntry != null) {
+ urlText.setText(selectedEntry.getUrl().toString());
+ fileMatchText.setText(selectedEntry.getFileMatch());
+ }
+ Button browse = new Button(container,SWT.PUSH);
+ browse.setText(JSONUIMessages.Browse);
+ browse.addSelectionListener(new SelectionListener(){
+
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE);
+ String result = dialog.open();
+ if (result == null || result.trim().length() == 0) {
+ return;
+ }
+ try {
+ String urlString = new File(result).toURI().toURL().toString();
+ urlText.setText(urlString);
+ } catch (MalformedURLException e1) {
+ urlText.setText("file:///" + result); //$NON-NLS-1$
+ }
+ }
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+
+ return parentComposite;
+ }
+
+ private boolean validatePage() {
+ fileMatch = null;
+ url = null;
+ if (fileMatchText.getText().trim().length() <= 0) {
+ setErrorMessage(JSONUIMessages.The_name_field_is_required);
+ return updateButton(false);
+ }
+ Set<UserEntry> list = entries.getEntries();
+ for(UserEntry entry:list) {
+ if (entry != selectedEntry && fileMatchText.getText().equals(entry.getFileMatch())) {
+ setErrorMessage(JSONUIMessages.The_entry_already_exists);
+ return updateButton(false);
+ }
+ }
+ if (urlText.getText().trim().length() <= 0) {
+ setErrorMessage(JSONUIMessages.The_url_field_is_required);
+ return updateButton(false);
+ }
+ try {
+ @SuppressWarnings("unused")
+ URL url = new URL(urlText.getText());
+ } catch (MalformedURLException e) {
+ setErrorMessage(JSONUIMessages.Invalid_URL);
+ return updateButton(false);
+ }
+ setErrorMessage(null);
+ fileMatch = fileMatchText.getText();
+ try {
+ url = new URL(urlText.getText()).toURI();
+ } catch (MalformedURLException ignore) {
+ } catch (URISyntaxException ignore) {
+ }
+ return updateButton(true);
+ }
+
+ private boolean updateButton(boolean enabled) {
+ if (okButton != null) {
+ okButton.setEnabled(enabled);
+ }
+ return false;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ okButton = createButton(parent, IDialogConstants.OK_ID,
+ IDialogConstants.OK_LABEL, true);
+ okButton.setEnabled(selectedEntry != null);
+ createButton(parent, IDialogConstants.CANCEL_ID,
+ IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ public String getFileMatch() {
+ return fileMatch;
+ }
+
+ public URI getURL() {
+ return url;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/JSONCatalogPreferencePage.java b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/JSONCatalogPreferencePage.java
new file mode 100644
index 0000000000..24fc4a8eca
--- /dev/null
+++ b/bundles/org.eclipse.wst.json.ui/src/org/eclipse/wst/json/ui/internal/preferences/JSONCatalogPreferencePage.java
@@ -0,0 +1,263 @@
+/*************************************************************************************
+ * Copyright (c) 2016 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * JBoss by Red Hat - Initial implementation.
+ ************************************************************************************/
+package org.eclipse.wst.json.ui.internal.preferences;
+
+import java.net.URI;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.wst.json.core.JSONCorePlugin;
+import org.eclipse.wst.json.core.internal.schema.catalog.EntryParser;
+import org.eclipse.wst.json.core.internal.schema.catalog.UserEntries;
+import org.eclipse.wst.json.core.internal.schema.catalog.UserEntry;
+import org.eclipse.wst.json.schemaprocessor.internal.JSONSchemaProcessor;
+import org.eclipse.wst.json.ui.internal.JSONUIMessages;
+import org.eclipse.wst.json.ui.internal.JSONUIPlugin;
+
+public class JSONCatalogPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private TreeViewer viewer;
+ private UserEntries entries;
+ private UserEntry selectedEntry;
+
+ public void init(IWorkbench workbench) {
+ }
+
+ @Override
+ protected void performDefaults() {
+ storePreferences();
+ super.performDefaults();
+ }
+
+ @Override
+ public boolean performOk() {
+ storePreferences();
+ return super.performOk();
+ }
+
+ private void storePreferences() {
+ IEclipsePreferences prefs = getPreferences();
+ try {
+ String value = new EntryParser().serialize(entries.getEntries());
+ prefs.put(EntryParser.JSON_CATALOG_ENTRIES, value);
+ JSONCorePlugin.getDefault().clearCatalogCache();
+ JSONSchemaProcessor.clearCache();
+ } catch (Exception e) {
+ logException(e);
+ }
+ }
+
+ private static IEclipsePreferences getPreferences() {
+ IEclipsePreferences preferences = InstanceScope.INSTANCE
+ .getNode("org.eclipse.wst.json.ui"); //$NON-NLS-1$
+ return preferences;
+ }
+
+ private static void logException(Exception e) {
+ IStatus status = new Status(IStatus.ERROR, JSONUIPlugin.PLUGIN_ID, e
+ .getLocalizedMessage(), e);
+ JSONUIPlugin.getDefault().getLog().log(status);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ composite.setLayout(layout);
+
+ Group entriesGroup = new Group(composite, SWT.NONE);
+ entriesGroup.setText(JSONUIMessages.JSON_Catalog_Entries);
+ GridLayout gl = new GridLayout(2, false);
+ entriesGroup.setLayout(gl);
+ entriesGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ viewer = new TreeViewer(entriesGroup, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ viewer.setContentProvider(new EntriesContentProvider());
+ viewer.setLabelProvider(new EntriesLabelProvider());
+ entries = new UserEntries();
+ entries.getEntries().addAll(EntryParser.getUserEntries());
+ viewer.setInput(entries);
+ viewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+ viewer.expandAll();
+
+ Composite buttonComposite = new Composite(entriesGroup, SWT.NONE);
+ buttonComposite.setLayout(new GridLayout(1, false));
+ buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+
+ Button addButton = new Button(buttonComposite, SWT.PUSH);
+ addButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ addButton.setText(JSONUIMessages.Add);
+ addButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ EntryDialog dialog = new EntryDialog(getShell(), null, entries);
+ int ok = dialog.open();
+ if (ok == Window.OK) {
+ String fileMatch = dialog.getFileMatch();
+ if (fileMatch != null) {
+ URI url = dialog.getURL();
+ UserEntry entry = new UserEntry();
+ entry.setUrl(url);
+ entry.setFileMatch(fileMatch);
+ entries.add(entry);
+ viewer.refresh();
+ }
+ }
+ }
+ });
+ final Button editButton = new Button(buttonComposite, SWT.PUSH);
+ editButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ editButton.setText(JSONUIMessages.Edit);
+ editButton.setEnabled(false);
+ editButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ if (selectedEntry == null) {
+ return;
+ }
+ EntryDialog dialog = new EntryDialog(getShell(), selectedEntry, entries);
+ int ok = dialog.open();
+ if (ok == Window.OK) {
+ String fileMatch = dialog.getFileMatch();
+ if (fileMatch != null) {
+ URI url = dialog.getURL();
+ UserEntry entry = selectedEntry;
+ entry.setUrl(url);
+ entry.setFileMatch(fileMatch);
+ viewer.refresh();
+ }
+ }
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+ final Button removeButton = new Button(buttonComposite, SWT.PUSH);
+ removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ removeButton.setText(JSONUIMessages.Remove);
+ removeButton.setEnabled(false);
+
+ removeButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ if (selectedEntry != null) {
+ entries.getEntries().remove(selectedEntry);
+ viewer.refresh();
+ }
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ public void selectionChanged(SelectionChangedEvent event) {
+ editButton.setEnabled(false);
+ removeButton.setEnabled(false);
+ selectedEntry = null;
+ ISelection selection = event.getSelection();
+ if (selection instanceof ITreeSelection) {
+ ITreeSelection treeSelection = (ITreeSelection) selection;
+ Object object = treeSelection.getFirstElement();
+ if (object instanceof UserEntry) {
+ selectedEntry = (UserEntry) object;
+ editButton.setEnabled(true);
+ removeButton.setEnabled(true);
+ }
+ }
+ }
+ });
+
+ return composite;
+ }
+
+ class EntriesContentProvider implements ITreeContentProvider {
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof UserEntries) {
+ return ((UserEntries) parentElement).getEntries().toArray();
+ }
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ return element instanceof UserEntries;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+ class EntriesLabelProvider extends LabelProvider {
+
+ @Override
+ public Image getImage(Object element) {
+ return super.getImage(element);
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof UserEntry) {
+ UserEntry entry = (UserEntry) element;
+ String result = entry.getFileMatch();
+ return result;
+ }
+ return super.getText(element);
+ }
+
+ }
+
+}

Back to the top