All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.karaf.webconsole.features.FeaturesPlugin Maven / Gradle / Ivy

There is a newer version: 4.4.6
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.karaf.webconsole.features;


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.features.Repository;
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.json.JSONException;
import org.json.JSONWriter;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * WebConsole plugin to use {@link FeaturesService}.
 */
public class FeaturesPlugin extends AbstractWebConsolePlugin {

    private final Logger log = LoggerFactory.getLogger(FeaturesPlugin.class);

    public static final String NAME = "features";
    public static final String LABEL = "Features";
    private ClassLoader classLoader;
    private String featuresJs = "/features/res/ui/features.js";
    private FeaturesService featuresService;
    private BundleContext bundleContext;

    @Override
    protected boolean isHtmlRequest(HttpServletRequest request) {
        return false;
    }

    public void start() {
        super.activate(bundleContext);
        this.classLoader = this.getClass().getClassLoader();
        this.log.info(LABEL + " plugin activated");
    }

    public void stop() {
        this.log.info(LABEL + " plugin deactivated");
        super.deactivate();
    }

    @Override
    public String getLabel() {
        return NAME;
    }

    @Override
    public String getTitle() {
        return LABEL;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        boolean success = false;

        final String action = req.getParameter("action");
        final String feature = req.getParameter("feature");
        final String version = req.getParameter("version");
        final String url = req.getParameter("url");

        if (action == null) {
            success = true;
        } else if ("installFeature".equals(action)) {
            success = this.installFeature(feature, version);
        } else if ("uninstallFeature".equals(action)) {
            success = this.uninstallFeature(feature, version);
        } else if ("refreshRepository".equals(action)) {
            success = this.refreshRepository(url);
        } else if ("removeRepository".equals(action)) {
            success = this.removeRepository(url);
        } else if ("addRepository".equals(action)) {
            success = this.addRepository(url);
        }

        if (success) {
            // let's wait a little bit to give the framework time
            // to process our request
            try {
                Thread.sleep(800);
            } catch (InterruptedException e) {
                // ignore
            }
            this.renderJSON(resp);
        } else {
            super.doPost(req, resp);
        }
    }

    @Override
    protected void renderContent(HttpServletRequest request, HttpServletResponse response) throws IOException {

        final PrintWriter pw = response.getWriter();

        String appRoot = (String) request.getAttribute(WebConsoleConstants.ATTR_APP_ROOT);

        final String featuresScriptTag = "";
        pw.println(featuresScriptTag);

        pw.println("");

        pw.println("
"); pw.println(""); } protected URL getResource(String path) { path = path.substring(NAME.length() + 1); if (path == null || path.isEmpty()) { return null; } URL url = this.classLoader.getResource(path); if (url != null) { InputStream ins = null; try { ins = url.openStream(); if (ins == null) { this.log.error("failed to open " + url); url = null; } } catch (IOException e) { this.log.error(e.getMessage(), e); url = null; } finally { if (ins != null) { try { ins.close(); } catch (IOException e) { this.log.error(e.getMessage(), e); } } } } return url; } private boolean installFeature(String feature, String version) { boolean success = false; if (featuresService == null) { this.log.error("Features service is not available"); } try { featuresService.installFeature(feature, version); success = true; } catch (Exception e) { this.log.error("Can't install feature {}/{}", feature, version, e); } return success; } private boolean uninstallFeature(String feature, String version) { boolean success = false; if (featuresService == null) { this.log.error("Features service is not available"); } try { featuresService.uninstallFeature(feature, version); success = true; } catch (Exception e) { this.log.error("Can't uninstall feature {}/{}", feature, version, e); } return success; } private boolean removeRepository(String url) { boolean success = false; if (featuresService == null) { this.log.error("Features service is not available"); } try { featuresService.removeRepository(new URI(url)); success = true; } catch (Exception e) { this.log.error("Can't remove features repository {}", url, e); } return success; } private boolean refreshRepository(String url) { boolean success = false; if (featuresService == null) { this.log.error("Features service is not available"); } try { featuresService.removeRepository(new URI(url)); featuresService.addRepository(new URI(url)); success = true; } catch (Exception e) { this.log.error("Can't refresh features repository {}", url, e); } return success; } private boolean addRepository(String url) { boolean success = false; if (featuresService == null) { this.log.error("Features service is not available"); } try { featuresService.addRepository(new URI(url)); success = true; } catch (Exception e) { this.log.error("Can't add features repository {}", url, e); } return success; } private void renderJSON(final HttpServletResponse response) throws IOException { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); final PrintWriter pw = response.getWriter(); writeJSON(pw); } private void writeJSON(final PrintWriter pw) throws IOException { final List repositories = this.getRepositories(); final List features = this.getFeatures(repositories); final String statusLine = this.getStatusLine(features); final JSONWriter jw = new JSONWriter(pw); try { jw.object(); jw.key("status"); jw.value(statusLine); jw.key("repositories"); jw.array(); for (Repository r : repositories) { jw.object(); jw.key("name"); jw.value(r.getName()); jw.key("url"); String uri = r.getURI().toString(); jw.value(uri); jw.key("actions"); jw.array(); boolean enable = true; if (uri.startsWith("bundle")) { enable = false; } action(jw, enable, "refreshRepository", "Refresh", "refresh"); action(jw, enable, "removeRepository", "Remove", "delete"); jw.endArray(); jw.endObject(); } jw.endArray(); jw.key("features"); jw.array(); for (ExtendedFeature f : features) { featureInfo(jw, f); } jw.endArray(); jw.endObject(); } catch (JSONException je) { throw new IOException(je.toString()); } } private List getRepositories() { List repositories = new ArrayList(); if (featuresService == null) { this.log.error("Features service is not available"); return repositories; } try { for (Repository r : featuresService.listRepositories()) { repositories.add(r); } } catch (Exception e) { this.log.error(e.getMessage()); } return repositories; } private List getFeatures(List repositories) { List features = new ArrayList(); if (featuresService == null) { this.log.error("Features service is not available"); return features; } try { for (Repository r : repositories) { for (Feature f : r.getFeatures()) { ExtendedFeature.State state = featuresService.isInstalled(f) ? ExtendedFeature.State.INSTALLED : ExtendedFeature.State.UNINSTALLED; features.add(new ExtendedFeature(state, r.getName(), f)); } } } catch (Exception e) { this.log.error(e.getMessage()); } Collections.sort(features, new ExtendedFeatureComparator()); return features; } class ExtendedFeatureComparator implements Comparator { @Override public int compare(ExtendedFeature o1, ExtendedFeature o2) { return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase()); } } private String getStatusLine(final List features) { int installed = 0; for (ExtendedFeature f : features) { if (f.getState() == ExtendedFeature.State.INSTALLED) { installed++; } } final StringBuffer buffer = new StringBuffer(); buffer.append("Feature information: "); appendFeatureInfoCount(buffer, "in total", features.size()); if (installed == features.size()) { buffer.append(" - all "); appendFeatureInfoCount(buffer, "active.", features.size()); } else { if (installed != 0) { buffer.append(", "); appendFeatureInfoCount(buffer, "installed", installed); } buffer.append('.'); } return buffer.toString(); } private void appendFeatureInfoCount(final StringBuffer buf, String msg, int count) { buf.append(count); buf.append(" feature"); if (count != 1) buf.append('s'); buf.append(' '); buf.append(msg); } private void featureInfo(JSONWriter jw, ExtendedFeature feature) throws JSONException { jw.object(); jw.key("id"); jw.value(feature.getId()); jw.key("name"); jw.value(feature.getName()); jw.key("version"); jw.value(feature.getVersion()); jw.key("repository"); jw.value(feature.getRepository()); jw.key("state"); ExtendedFeature.State state = feature.getState(); jw.value(state.toString()); jw.key("actions"); jw.array(); if (state == ExtendedFeature.State.INSTALLED) { action(jw, true, "uninstallFeature", "Uninstall", "delete"); } else if (state == ExtendedFeature.State.UNINSTALLED) { action(jw, true, "installFeature", "Install", "start"); } jw.endArray(); jw.endObject(); } private void action(JSONWriter jw, boolean enabled, String op, String title, String image) throws JSONException { jw.object(); jw.key("enabled").value(enabled); jw.key("op").value(op); jw.key("title").value(title); jw.key("image").value(image); jw.endObject(); } public void setFeaturesService(FeaturesService featuresService) { this.featuresService = featuresService; } public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy