Package scala.tools.eclipse.contribution.weaving.jdt.configuration

Source Code of scala.tools.eclipse.contribution.weaving.jdt.configuration.WeavingStateConfigurer

/*******************************************************************************
* Copyright (c) 2009 SpringSource 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:
*     Andrew Eisenberg - initial API and implementation
*******************************************************************************/

/*******************************************************************************
* Added to the Scala plugin to fix interoperability issues between the
* Spring IDE and the Scala IDE. This plugin now implements the cuprovider and
* imagedescriptorselector extension points, previously provided by the
* JDT weaving plugin.
*
* Repo: git://git.eclipse.org/gitroot/ajdt/org.eclipse.ajdt.git
* File: src/org.eclipse.contribution.weaving.jdt/src/org/eclipse/contribution/jdt/preferences/WeavingStateConfigurer.java
*
*******************************************************************************/

package scala.tools.eclipse.contribution.weaving.jdt.configuration;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URL;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.simpleconfigurator.manipulator.SimpleConfiguratorManipulatorImpl;
import org.eclipse.equinox.simpleconfigurator.manipulator.SimpleConfiguratorManipulator;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.DisabledInfo;
import org.eclipse.osgi.service.resolver.State;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;

import scala.tools.eclipse.contribution.weaving.jdt.ScalaJDTWeavingPlugin;
import scala.tools.eclipse.contribution.weaving.jdt.configuration.IsWovenTester;

/**
* @author Andrew Eisenberg
* @created Jan 19, 2009
*
* Object that controls the state of the Equinox aspects weaver
*/
public class WeavingStateConfigurer {
   
    private final static Version MIN_WEAVER_VERSION = new Version(1, 6, 1);

    private final static boolean IS_WEAVING = IsWovenTester.isWeavingActive();

   
    public String getWeaverVersionInfo() {
        BundleDescription weaver =
            Platform.getPlatformAdmin().getState(false).
            getBundle("org.aspectj.weaver", null);
       
        if (weaver != null) {
            if (MIN_WEAVER_VERSION.compareTo(weaver.getVersion()) <= 0) {
                return "";
//                return "AspectJ weaver version " + weaver.getVersion().toString() + " OK!";
            } else {
                return "No compatible version of org.aspectj.weaver found.  " +
                "JDT Weaving requires 1.6.1 or higher.  Found version " +
                weaver.getVersion();
            }
        } else {
            return "org.aspectj.weaver not installed.  JDT Weaving requires 1.6.3 or higher.";
        }
    }
   
    public IStatus changeWeavingState(boolean becomeEnabled) {
        // now, weaving service is controlled by
        // starting and stopping weaving.aspectj bundle
        // this method is used only to ensure the hook exists
        IStatus success;
        boolean isCurrentlyWeaving = false;
        try {
            isCurrentlyWeaving = currentConfigStateIsWeaving();
        } catch (Exception e) {
            ScalaJDTWeavingPlugin.logException(e);
        }
        if (becomeEnabled && !isCurrentlyWeaving) {
            success = changeConfigDotIni(becomeEnabled);
        } else {
            // do nothing
            success = Status.OK_STATUS;
        }
       
       
        IStatus success2 = changeAutoStartupAspectsBundle(becomeEnabled);
       
        IStatus success3 = changeSimpleConfiguratorManipulator(becomeEnabled);
        if (success.getSeverity() >= IStatus.ERROR || success2.getSeverity() >= IStatus.ERROR || success3.getSeverity() >= IStatus.ERROR) {
            return new MultiStatus(ScalaJDTWeavingPlugin.ID, IStatus.ERROR,
                    new IStatus[] { success, success2, success3, getInstalledBundleInformation() }, "Could not "
                    + (becomeEnabled ? "ENABLED" : "DISABLED") + " weaving service",
                    null);
        } else if (success.getSeverity() >= IStatus.WARNING || success2.getSeverity() >= IStatus.WARNING || success3.getSeverity() >= IStatus.WARNING) {
            return new MultiStatus(ScalaJDTWeavingPlugin.ID, IStatus.WARNING,
                    new IStatus[] { success, success2, success3, getInstalledBundleInformation() }, "Weaving service "
                    + (becomeEnabled ? "ENABLED" : "DISABLED") + " with warnings",
                    null);
        } else {
            // if successful, also schedule to ask for reindexing on startup
            if (becomeEnabled) {
              // We don't ask to reindex (anyway, the Scala nature was not part of the 'weavable natures' list)
              // while using the JDT weaving plugin
//                JDTWeavingPreferences.setAskToReindex(true);
            }
            return new MultiStatus(ScalaJDTWeavingPlugin.ID, IStatus.OK,
                    new IStatus[] { getInstalledBundleInformation() },
                    "Weaving service successfully "
                    + (becomeEnabled ? "ENABLED" : "DISABLED"), null);
        }
    }

    /**
     * Change the default startup state of the aspectj weaving bundle using the
     * {@link SimpleConfiguratorManipulator}
     * @param becomeEnabled if true, then ensure that the bundle is set to autostarted
     * if false, the bundle should not be autostarted
     * @return {@link Status#OK_STATUS} if all goes well, otherwise returns the exception
     */
    private IStatus changeSimpleConfiguratorManipulator(boolean becomeEnabled) {
        SimpleConfiguratorManipulator manipulator = new SimpleConfiguratorManipulatorImpl();
        BundleContext bundleContext = null;
        try {
            bundleContext = Platform.getBundle(ScalaJDTWeavingPlugin.ID).getBundleContext();
        } catch (Exception e) {
            return new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Cannot get bundleContext", e);
        }
        if (bundleContext == null) {
            return new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Cannot get bundleContext", new Exception());
        }
       
        try {
            BundleInfo[] infos = manipulator.loadConfiguration(bundleContext, null);
            BundleInfo weavingInfo = null;
            for (BundleInfo info : infos) {
                if (info.getSymbolicName().equals("org.eclipse.equinox.weaving.aspectj")) {
                    weavingInfo = info;
                    break;
                }
            }
            if (weavingInfo == null) {
                return new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Could not find equinox aspects bundle", new Exception());
            }
           
            weavingInfo.setMarkedAsStarted(becomeEnabled);
           
            URL configURL = Platform.getConfigurationLocation().getURL();
            if (configURL == null || !"file".equals(configURL.getProtocol())) {
                throw new IOException("Platform configuration location is not found: " + configURL);
            }
           
            URL installURL = Platform.getInstallLocation().getURL();
            if (installURL == null || !"file".equals(installURL.getProtocol())) {
                throw new IOException("Platform install location is not found: " + installURL);
            }
            manipulator.saveConfiguration(infos, new File(configURL.getFile() + SimpleConfiguratorManipulator.BUNDLES_INFO_PATH), new File(installURL.getFile()).toURI());
           
            return Status.OK_STATUS;
        } catch (IOException e) {
            return new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Cannot load configuration", e);
        }
    }

    private IStatus getInstalledBundleInformation() {
        StringBuffer sb = new StringBuffer();
        sb.append("Information on currently installed bundles:\n");
       
        Bundle[] allEABundles = Platform.getBundles("org.eclipse.equinox.weaving.aspectj", null); //$NON-NLS-1$
        if (allEABundles != null) {
            for (int i = 0; i < allEABundles.length; i++) {
                Bundle bundle = allEABundles[i];
                sb.append(createBundleNameString(bundle));
            }
        } else {
            sb.append("org.eclipse.equinox.weaving.aspectj not installed\n");
        }
       
        Bundle[] allWeaverBundles = Platform.getBundles("org.aspectj.weaver", null);
        if (allWeaverBundles != null) {
            for (int i = 0; i < allWeaverBundles.length; i++) {
                Bundle bundle = allWeaverBundles[i];
                sb.append(createBundleNameString(bundle));
            }
        } else {
            sb.append("org.aspectj.weaver not installed\n");
        }
       
        allWeaverBundles = Platform.getBundles("com.springsource.org.aspectj.weaver", null);
        if (allWeaverBundles != null) {
            for (int i = 0; i < allWeaverBundles.length; i++) {
                Bundle bundle = allWeaverBundles[i];
                sb.append(createBundleNameString(bundle));
            }
        } else {
            sb.append("com.springsource.org.aspectj.weaver not installed\n");
        }
       
        Bundle[] allWeavingHooks = Platform.getBundles("org.eclipse.equinox.weaving.hook", null);
        if (allWeavingHooks != null) {
            for (int i = 0; i < allWeavingHooks.length; i++) {
                Bundle bundle = allWeavingHooks[i];
                sb.append(createBundleNameString(bundle));
            }
        } else {
            sb.append("org.eclipse.equinox.weaving.hook not installed\n");
        }

       
        return new Status(IStatus.INFO, ScalaJDTWeavingPlugin.ID, sb.toString());
    }

    private StringBuffer createBundleNameString(Bundle bundle) {
        StringBuffer sb = new StringBuffer();
        sb.append(bundle.getSymbolicName()).append("_")
            .append(bundle.getVersion()).append(" : ID ")
            .append(bundle.getBundleId()).append(": STATE ");
        switch (bundle.getState()) {
            case Bundle.ACTIVE:
                sb.append("ACTIVE");
                break;

            case Bundle.INSTALLED:
                sb.append("INSTALLED");
                break;

            case Bundle.RESOLVED:
                sb.append("RESOLVED");
                break;

            case Bundle.STARTING:
                sb.append("STARTING");
                break;

            case Bundle.STOPPING:
                sb.append("STOPPING");
                break;
        }
       
        sb.append("\n");
        return sb;
    }
   
    private IStatus changeAutoStartupAspectsBundle(boolean becomeEnabled) {
       
        // get all versions of weaving.aspectj in the platform. 
        // disable and stop all but the most receent
        Bundle[] allEABundles = Platform.getBundles("org.eclipse.equinox.weaving.aspectj", null); //$NON-NLS-1$
        if (allEABundles == null || allEABundles.length == 0) {
            return new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Could not find org.eclipse.equinox.weaving.aspectj" +
                " so weaving service cannot be " +
                (becomeEnabled ? "enabled" : "disabled") + ".");
        }
        try {
            State state = Platform.getPlatformAdmin().getState(false);
            if (becomeEnabled) {
                allEABundles[0].start();
                for (int i = 1; i < allEABundles.length; i++) {
                    allEABundles[i].stop();
                    BundleDescription desc = state.getBundle(allEABundles[i].getBundleId());
                    DisabledInfo info = new DisabledInfo(
                            "org.eclipse.contribution.weaving.jdt", //$NON-NLS-1$
                            "Disabled older version of Equinox Aspects", desc); //$NON-NLS-1$
                    try {
                        Platform.getPlatformAdmin().addDisabledInfo(info);
                    } catch (IllegalArgumentException e) {
                        // can ignore
                    }
                }
            } else {
                for (int i = 0; i < allEABundles.length; i++) {
                    switch(allEABundles[i].getState()) {
                        case Bundle.ACTIVE:
                        case Bundle.INSTALLED:
                        case Bundle.STARTING:
                        case Bundle.RESOLVED:
                            allEABundles[i].stop();
                    }
                }
            }
           
            return Status.OK_STATUS;
        } catch (Exception e) {
            return new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Error occurred in setting org.eclipse.equinox.weaving.aspectj to autostart" +
                    " so weaving service cannot be " +
                    (becomeEnabled ? "enabled" : "disabled") + ".", e);
        }
    }

    private IStatus changeConfigDotIni(boolean becomeEnabled) {
       
        // a little crude find the config.ini go through each
        // line and filter out the osgi.framework.extensions line
        IStatus success;
        try {
            String configArea = getConfigArea();
            File f = new File(new URI(configArea));
            if (f.canWrite()) {
                BufferedReader br = new BufferedReader(new FileReader(f));
               
                String newConfig = internalChangeWeavingState(becomeEnabled, br);
                BufferedWriter bw = new BufferedWriter(new FileWriter(f));
                bw.write(newConfig);
                bw.close();
   
               
                if (becomeEnabled == currentConfigStateIsWeaving()) {
                    success = Status.OK_STATUS;
                } else {
                    success = new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, "Could not add or remove org.eclipse.equinox.weaving.hook as a framework adaptor.");
                }
            } else {
                // cannot write to file...most likely this is because the config.ini
                // is in a global location that is read-only.
                success = new Status(IStatus.WARNING, ScalaJDTWeavingPlugin.ID, "Could not add " +
                    "'osgi.framework.extensions=org.eclipse.equinox.weaving.hook'\n " +
                    "to the config.ini because the file is read-only.  Weaving may not be enabled.");
            }
        } catch (Exception e) {
            success = new Status(IStatus.ERROR, ScalaJDTWeavingPlugin.ID, e
                    .getMessage(), e);
        }
        return success;
    }

    protected String internalChangeWeavingState(boolean becomeEnabled,
            BufferedReader br) throws IOException {
        StringBuffer sb = new StringBuffer();
        String line = null;
        boolean hookAdded = false;
        while ((line = br.readLine()) != null) {
            if (line.trim().startsWith("osgi.framework.extensions=")) {
                String[] split = line.split("=");
                if (split.length > 1) {
                    String[] extNames = split[1].split(",");
                    boolean shouldAddLine = false;
                    StringBuffer sb2 = new StringBuffer();
                    sb2.append("osgi.framework.extensions=");
                    for (int i = 0; i < extNames.length; i++) {
                        String extName = extNames[i].trim();
                        // don't add hook, we add it later in needed
                        if (!extName.equals("org.eclipse.equinox.weaving.hook")) {
                            sb2.append(extName + ",");
                            shouldAddLine = true;
                        }
                    }
                    if (shouldAddLine) {
                        if (becomeEnabled) {
                            sb2.append("org.eclipse.equinox.weaving.hook\n");
                            hookAdded = true;
                        } else {
                            // replace last comma
                            sb2.replace(sb2.length() - 1, sb2.length(), "\n");
                        }
                        sb.append(sb2);
                    }
                }
            } else {
                sb.append(line + "\n");
            }
        }

        // if line didn't exist before
        if (becomeEnabled && !hookAdded) {
            sb.append("osgi.framework.extensions=org.eclipse.equinox.weaving.hook\n");
        }
        try {
            br.close();
        } catch (IOException e) {
            ScalaJDTWeavingPlugin.logException(e);
        }
        return sb.toString();
    }

    private String getConfigArea() {
        String configArea = System.getProperty("osgi.configuration.area") + "config.ini";
        configArea = configArea.replaceAll(" ", "%20");
        return configArea;
    }
   
   
    public boolean currentConfigStateIsWeaving() throws Exception {
        String configArea = getConfigArea();
       
        File f = new File(new URI(configArea));
        if (! f.exists()) {
            throw new FileNotFoundException("Could not find config file: " + f.getAbsolutePath());
        }
        if (! f.canWrite()) {
            throw new IOException("Could not write to config file: " + f.getAbsolutePath());
        }
        BufferedReader br = new BufferedReader(new FileReader(f));
        return internalCurrentConfigStateIsWeaving(br);
    }

    protected boolean internalCurrentConfigStateIsWeaving(BufferedReader br)
            throws IOException {
        String line = null;
        while ((line = br.readLine()) != null) {
            if (line.trim().startsWith("osgi.framework.extensions=") &&
                    line.contains("org.eclipse.equinox.weaving.hook")) {
                return true;
            }
        }
        return false;
    }
   
    public boolean isWeaving() {
        return IS_WEAVING;
    }
}
TOP

Related Classes of scala.tools.eclipse.contribution.weaving.jdt.configuration.WeavingStateConfigurer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.