blob: 20efdb3ae4d8abd128793528f5490162aad32cda [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Remain Software
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* wim.jongman@remainsoftware.com - initial API and implementation
*******************************************************************************/
package org.eclipse.tips.json;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.ArrayList;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.tips.core.Tip;
import org.eclipse.tips.core.TipImage;
import org.eclipse.tips.core.TipProvider;
import org.eclipse.tips.core.internal.LogUtil;
import org.eclipse.tips.json.internal.JsonConstants;
import org.eclipse.tips.json.internal.JsonHTMLTip;
import org.eclipse.tips.json.internal.JsonUrlTip;
import org.eclipse.tips.json.internal.Util;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
* A special TipProvider that gets instantiated from a JSon file.
*
*/
@SuppressWarnings("restriction")
public abstract class JsonTipProvider extends TipProvider {
private static final String SPACE = " "; //$NON-NLS-1$
private URL fJsonUrl;
private String fDescription;
private String fImage;
private JsonObject fJsonObject;
/**
* A method to set the a url containing a JSon file that describes this tip
* provider.
*
* @param jsonUrl the uRL to the Json file describing the provider and tips
* @throws MalformedURLException in case of an incorrect URL
*/
public void setJsonUrl(String jsonUrl) throws MalformedURLException {
fJsonUrl = new URL(jsonUrl);
}
/**
*
* {@inheritDoc}
*
* <p>
* <b>Implementation Details</b><br>
* The implementation of this method in this provider will parse the json file
* which was set with {@link #setJsonUrl(String)}.
*
*/
@Override
public synchronized IStatus loadNewTips(IProgressMonitor monitor) {
SubMonitor subMonitor = SubMonitor.convert(monitor);
ArrayList<Tip> result = new ArrayList<>();
try {
subMonitor.beginTask(getDescription() + SPACE + Messages.JsonTipProvider_1, -1);
fJsonObject = loadJsonObject();
if (fJsonObject == null) {
return new Status(IStatus.INFO, "org.eclipse.tips.json",
MessageFormat.format("Could not parse json for {0}. Cache invalidated.", getID()), null);
}
JsonObject provider = fJsonObject.getAsJsonObject(JsonConstants.P_PROVIDER);
fDescription = Util.getValueOrDefault(provider, JsonConstants.P_DESCRIPTION, "not set"); //$NON-NLS-1$
fImage = Util.getValueOrDefault(provider, JsonConstants.P_IMAGE, null);
setExpression(Util.getValueOrDefault(provider, JsonConstants.P_EXPRESSION, null));
JsonArray tips = provider.getAsJsonArray(JsonConstants.P_TIPS);
subMonitor.beginTask(getDescription() + SPACE + Messages.JsonTipProvider_2, -1);
tips.forEach(parm -> result.add(createJsonTip(parm)));
} catch (Exception e) {
Status status = new Status(IStatus.ERROR, "org.eclipse.tips.json", e.getMessage(), e); //$NON-NLS-1$
getManager().log(status);
return status;
}
getManager().log(LogUtil.info(MessageFormat.format(Messages.JsonTipProvider_4, result.size() + ""))); //$NON-NLS-1$
setTips(result);
subMonitor.done();
return Status.OK_STATUS;
}
private JsonObject loadJsonObject() throws IOException {
try (InputStream stream = fJsonUrl.openStream(); InputStreamReader reader = new InputStreamReader(stream)) {
Object result = new JsonParser().parse(reader);
if (result instanceof JsonObject) {
return (JsonObject) result;
} else {
return null;
}
}
}
@Override
public TipImage getImage() {
if (fImage == null) {
return null;
}
return new TipImage(fImage);
}
@Override
public String getDescription() {
return fDescription;
}
private Tip createJsonTip(JsonElement parm) {
JsonObject json = (JsonObject) parm;
replaceVariables(json);
try {
if (json.get(JsonConstants.T_URL) != null) {
return new JsonUrlTip(getID(), json);
} else {
return new JsonHTMLTip(getID(), json);
}
} catch (ParseException e) {
getManager().log(LogUtil.error(getClass(), e));
throw new RuntimeException(e);
}
}
private void replaceVariables(JsonObject pJson) {
String url = Util.getValueOrDefault(pJson, JsonConstants.T_URL, null);
String html = Util.getValueOrDefault(pJson, JsonConstants.T_HTML, null);
JsonObject vars = fJsonObject.getAsJsonObject(JsonConstants.P_PROVIDER)
.getAsJsonObject(JsonConstants.T_VARIABLES);
if (vars != null) {
if (url != null) {
url = Util.replace(vars, url);
pJson.remove(JsonConstants.T_URL);
pJson.addProperty(JsonConstants.T_URL, url);
}
if (html != null) {
html = Util.replace(vars, html);
pJson.remove(JsonConstants.T_HTML);
pJson.addProperty(JsonConstants.T_HTML, html);
}
}
}
@Override
public void dispose() {
}
}