Bug 462117 - [bower] JsonSyntaxException exception occurs in Bower IDE while installing angular dependency
Fix an issue while reading bower.json files
Author: Stéphane Bégaudeau <stephane.begaudeau@obeo.fr>
Signed-off-by: Stéphane Bégaudeau <stephane.begaudeau@obeo.fr>
Signed-off-by: vrubezhny <vrubezhny@exadel.com>
diff --git a/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/AbstractBowerCommand.java b/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/AbstractBowerCommand.java
index eda1e8f..3e86c83 100644
--- a/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/AbstractBowerCommand.java
+++ b/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/AbstractBowerCommand.java
@@ -13,6 +13,7 @@
import com.google.common.base.Optional;
import com.google.common.io.Files;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import java.io.BufferedReader;
@@ -45,7 +46,7 @@
* The prefixes to consider to determines if a package id is the URL of a Git repository or just its name.
*/
private static String[] PREFIXES = new String[] {IBowerConstants.GIT_PREFIX, IBowerConstants.HTTP_PREFIX,
- IBowerConstants.HTTPS_PREFIX, IBowerConstants.SSH_PREFIX };
+ IBowerConstants.HTTPS_PREFIX, IBowerConstants.SSH_PREFIX };
/**
* The URL of the bower server on which the request should be made.
@@ -305,7 +306,10 @@
for (String line : lines) {
content.append(line);
}
- return Optional.fromNullable(new Gson().fromJson(content.toString(), BowerJson.class));
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(BowerJson.class, new BowerJsonDeserializer());
+ Gson gson = gsonBuilder.create();
+ return Optional.fromNullable(gson.fromJson(content.toString(), BowerJson.class));
} catch (JsonSyntaxException e) {
logger.log(IBowerConstants.BOWER_CORE_BUNDLE_ID, ILogger.ERROR, e);
} catch (IOException e) {
diff --git a/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/BowerJsonDeserializer.java b/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/BowerJsonDeserializer.java
new file mode 100644
index 0000000..57a5af5
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.bower.core/src/main/java/org/eclipse/wst/jsdt/bower/core/api/BowerJsonDeserializer.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2015.
+ * 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:
+ * sbegaudeau - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.bower.core.api;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * @author sbegaudeau
+ */
+public class BowerJsonDeserializer implements JsonDeserializer<BowerJson> {
+
+ /**
+ * The name.
+ */
+ private static final String NAME = "name"; //$NON-NLS-1$
+
+ /**
+ * The description.
+ */
+ private static final String DESCRIPTION = "description"; //$NON-NLS-1$
+
+ /**
+ * Ther version.
+ */
+ private static final String VERSION = "version"; //$NON-NLS-1$
+
+ /**
+ * The homepage.
+ */
+ private static final String HOMEPAGE = "homepage"; //$NON-NLS-1$
+
+ /**
+ * Main files.
+ */
+ private static final String MAIN = "main"; //$NON-NLS-1$
+
+ /**
+ * Private.
+ */
+ private static final String PRIVATE = "private"; //$NON-NLS-1$
+
+ /**
+ * Licenses.
+ */
+ private static final String LICENSES = "licenses"; //$NON-NLS-1$
+
+ /**
+ * Ignore.
+ */
+ private static final String IGNORE = "ignore"; //$NON-NLS-1$
+
+ /**
+ * Authors.
+ */
+ private static final String AUTHORS = "authors"; //$NON-NLS-1$
+
+ /**
+ * Dependencies.
+ */
+ private static final String DEPENDENCIES = "dependencies"; //$NON-NLS-1$
+
+ /**
+ * DevDependencies.
+ */
+ private static final String DEV_DEPENDENCIES = "devDependencies"; //$NON-NLS-1$
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement, java.lang.reflect.Type,
+ * com.google.gson.JsonDeserializationContext)
+ */
+ @Override
+ public BowerJson deserialize(JsonElement json, Type type, JsonDeserializationContext context)
+ throws JsonParseException {
+ BowerJson bowerJson = new BowerJson();
+ if (json instanceof JsonObject) {
+ JsonObject jsonObject = (JsonObject)json;
+
+ // Basic properties: string
+ bowerJson.setName(this.getAsString(jsonObject, NAME));
+ bowerJson.setDescription(this.getAsString(jsonObject, DESCRIPTION));
+ bowerJson.setVersion(this.getAsString(jsonObject, VERSION));
+ bowerJson.setHomepage(this.getAsString(jsonObject, HOMEPAGE));
+
+ // Boolean
+ bowerJson.setPrivate(this.getAsBoolean(jsonObject, PRIVATE));
+
+ // Main: string or array of strings
+ bowerJson.setMain(this.getMain(jsonObject));
+
+ // List of string
+ bowerJson.setLicenses(this.getAsStringList(jsonObject, LICENSES));
+ bowerJson.setIgnore(this.getAsStringList(jsonObject, IGNORE));
+ bowerJson.setAuthors(this.getAsStringList(jsonObject, AUTHORS));
+
+ // Objects
+ bowerJson.setDependencies(this.getAsStringMap(jsonObject, DEPENDENCIES));
+ bowerJson.setDevDependencies(this.getAsStringMap(jsonObject, DEV_DEPENDENCIES));
+ }
+ return bowerJson;
+ }
+
+ /**
+ * Returns the value of the property with the given name in the given json object as a string.
+ *
+ * @param jsonObject
+ * The json object
+ * @param propertyName
+ * The name of the property
+ * @return The value of the property
+ */
+ private String getAsString(JsonObject jsonObject, String propertyName) {
+ String propertyValue = null;
+ JsonElement jsonElement = jsonObject.get(propertyName);
+ if (jsonElement != null && jsonElement.isJsonPrimitive()) {
+ propertyValue = jsonElement.getAsString();
+ }
+ return propertyValue;
+ }
+
+ /**
+ * Returns the value of the property with the given name in the given json object as a boolean.
+ *
+ * @param jsonObject
+ * The json object
+ * @param propertyName
+ * The name of the property
+ * @return The value of the property
+ */
+ private boolean getAsBoolean(JsonObject jsonObject, String propertyName) {
+ boolean propertyValue = false;
+ JsonElement jsonElement = jsonObject.get(propertyName);
+ if (jsonElement != null && jsonElement.isJsonPrimitive()) {
+ propertyValue = jsonElement.getAsBoolean();
+ }
+ return propertyValue;
+ }
+
+ /**
+ * Returns the value of the property main in the given json object as a string or a list of strings.
+ *
+ * @param jsonObject
+ * The json object
+ * @return The value of the property main
+ */
+ private List<String> getMain(JsonObject jsonObject) {
+ List<String> main = new ArrayList<String>();
+ JsonElement mainJsonElement = jsonObject.get(MAIN);
+ if (mainJsonElement != null) {
+ if (mainJsonElement.isJsonArray()) {
+ JsonArray mainJsonArray = mainJsonElement.getAsJsonArray();
+ for (JsonElement jsonElement : mainJsonArray) {
+ if (jsonElement.isJsonPrimitive()) {
+ main.add(jsonElement.getAsString());
+ }
+ }
+ } else if (mainJsonElement.isJsonPrimitive()) {
+ main.add(mainJsonElement.getAsString());
+ }
+ }
+ return main;
+ }
+
+ /**
+ * Returns the value of the property with the given name in the given json object as a list of strings.
+ *
+ * @param jsonObject
+ * The json object
+ * @param propertyName
+ * The name of the property
+ * @return The value of the property
+ */
+ private List<String> getAsStringList(JsonObject jsonObject, String propertyName) {
+ List<String> propertyValue = new ArrayList<String>();
+ JsonElement jsonElement = jsonObject.get(propertyName);
+ if (jsonElement != null && jsonElement.isJsonArray()) {
+ JsonArray jsonArray = jsonElement.getAsJsonArray();
+ for (JsonElement jsonChildElement : jsonArray) {
+ if (jsonChildElement.isJsonPrimitive()) {
+ propertyValue.add(jsonChildElement.getAsString());
+ }
+ }
+ }
+ return propertyValue;
+ }
+
+ /**
+ * Returns the value of the property with the given name in the given json object as a map of strings.
+ *
+ * @param jsonObject
+ * The json object
+ * @param propertyName
+ * The name of the property
+ * @return The value of the property
+ */
+ private Map<String, String> getAsStringMap(JsonObject jsonObject, String propertyName) {
+ Map<String, String> propertyValue = new HashMap<String, String>();
+ JsonElement jsonElement = jsonObject.get(propertyName);
+ if (jsonElement != null && jsonElement.isJsonObject()) {
+ JsonObject childJsonObject = jsonElement.getAsJsonObject();
+ Set<Entry<String, JsonElement>> entries = childJsonObject.entrySet();
+ for (Entry<String, JsonElement> entry : entries) {
+ if (entry.getValue().isJsonPrimitive()) {
+ propertyValue.put(entry.getKey(), entry.getValue().getAsString());
+ }
+ }
+ }
+ return propertyValue;
+ }
+
+}