/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed 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.guvnor.tools.utils.webdav;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * Utilities for dealing with streams.
 */
public class StreamProcessingUtils {

    private static final SimpleDateFormat CREATION_DATE_FORMAT = new SimpleDateFormat(
    "yyyy-MM-dd'T'HH:mm:ss'Z'");

    private static final SimpleDateFormat LAST_MODIFIED_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    protected static final SimpleDateFormat GUNVOR_TOOLS_DATE_FORMAT = new SimpleDateFormat(
            "EEE, dd MMM yyyy HH:mm:ss z", Locale.getDefault());

    public static String getStreamContents(InputStream is) throws IOException {
        byte[] buffer = new byte[1000];
          int c = 0;
          ByteArrayOutputStream bout = new ByteArrayOutputStream();
        while ((c = is.read(buffer)) != -1) {
              bout.write(buffer, 0, c);
          }

          return new String(bout.toByteArray());
    }

    private static String DAV_NS = "DAV:"; //$NON-NLS-1$

    public static Map<String, ResourceProperties> parseListing(String base, InputStream is) throws Exception {
        Map<String, ResourceProperties> res = new HashMap<String, ResourceProperties>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder parser = factory.newDocumentBuilder();
        Document doc = parser.parse(is);
        NodeList nl = doc.getElementsByTagNameNS(DAV_NS, "response"); //$NON-NLS-1$
        for (int i = 0; i < nl.getLength(); i++) {
            Element oneElem = (Element)nl.item(i);
            NodeList resName = oneElem.getElementsByTagNameNS(DAV_NS, "href"); //$NON-NLS-1$
            assert(resName.getLength() == 1);
            String bareName = extractOverlap(base, URLDecoder.decode(resName.item(0).getTextContent(), "UTF-8"));
            if (bareName.trim().length() > 0) {
                ResourceProperties props = new ResourceProperties();
                NodeList propList = oneElem.getElementsByTagNameNS(DAV_NS, "resourcetype"); //$NON-NLS-1$
                assert(propList.getLength() == 1);
                NodeList resTypeList = ((Element)propList.item(0)).getElementsByTagNameNS(DAV_NS, "collection"); //$NON-NLS-1$
                assert(resTypeList.getLength() < 2);
                if (resTypeList.getLength() == 1) {
                    props.setDirectory(true);
                }
                propList = oneElem.getElementsByTagNameNS(DAV_NS, "creationdate"); //$NON-NLS-1$
                if (propList.getLength() > 0) {
                    props.setCreationDate(propList.item(0).getTextContent());
                }
                propList = oneElem.getElementsByTagNameNS(DAV_NS, "getlastmodified"); //$NON-NLS-1$
                if (propList.getLength() > 0) {
                    props.setLastModifiedDate(propList.item(0).getTextContent());
                }
                String normBase = base.trim().endsWith("/")?base.trim():base.trim() + "/"; //$NON-NLS-1$ //$NON-NLS-2$
                props.setBase(normBase);
                res.put(bareName, props);
            }
        }
        return res;
    }

    private static String extractOverlap(String base, String extension) {
        String res = null;
        int pos = 0;
        int i = 1;
        boolean done = false;
        while (i < extension.length() && !done) {
            pos = base.lastIndexOf(extension.substring(0, i));
            if (pos == -1) {
                res = extension.substring(i - 1);
                done = true;
            }
            i++;
        }
        // If we got to the end of the loop above but !done,
        // that means the entire extension string matched in
        // base, so remove the entire extension contents
        if (!done) {
            res = ""; //$NON-NLS-1$
        }
        if (res.startsWith("/") && res.length() > 1) { //$NON-NLS-1$
            res = res.substring(1);
        }
//System.out.println("Returning " + res + " from " + base + ", " + extension);
        return res;
    }

    public static String parseISODateFormat(String dateStr) {

        if (dateStr == null)
            return null;

        String val = dateStr;

        try {
            if (dateStr.indexOf('T') == 10 && dateStr.endsWith("Z")) {
                Date date = CREATION_DATE_FORMAT.parse(dateStr);
                val = GUNVOR_TOOLS_DATE_FORMAT.format(date);

            } else if (dateStr.indexOf('T') == 10) {
                Date date = LAST_MODIFIED_DATE_FORMAT.parse(dateStr);
                val = GUNVOR_TOOLS_DATE_FORMAT.format(date);
            }

        }
        catch (ParseException e) {

        }

        return val;
    }
}


/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed 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.drools.eclipse.dsl.editor;

import org.drools.compiler.lang.dsl.DSLMappingEntry;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;

/**
 * Provides sorting for the natural language table viewer.
 */
public class DSLMappingSorter extends ViewerSorter {

    public final static int OBJECT = 0;
    public final static int EXPRESSION = 1;
    public final static int MAPPING = 2;
    public final static int SCOPE = 3;

    // Criteria that the instance uses
    private int criteria;

    /**
     * Creates a resource sorter that will use the given sort criteria.
     *
     * @param criteria the sort criterion to use: one of NAME or
     *   TYPE
     */
    public DSLMappingSorter(int criteria) {
        super();
        this.criteria = criteria;
    }

    /* (non-Javadoc)
     * Method declared on ViewerSorter.
     */
    public int compare(Viewer viewer, Object o1, Object o2) {

        DSLMappingEntry item1 = (DSLMappingEntry) o1;
        DSLMappingEntry item2 = (DSLMappingEntry) o2;

        switch (criteria) {
            case OBJECT:
                return compareObject(item1, item2);
            case EXPRESSION :
                return compareExpressions(item1, item2);
            case MAPPING :
                return compareMappings(item1, item2);
            case SCOPE :
                return compareScope(item1, item2);
            default:
                return 0;
        }
    }

    private int compareScope(DSLMappingEntry item1,
                             DSLMappingEntry item2) {
        return item1.getSection().compareTo( item2.getSection() );
    }

    private int compareMappings(DSLMappingEntry item1,
                                DSLMappingEntry item2) {
        return item1.getMappingValue().compareTo( item2.getMappingValue() );
    }

    private int compareExpressions(DSLMappingEntry item1,
                                   DSLMappingEntry item2) {
        return item1.getMappingKey().compareTo( item2.getMappingKey() );
    }

    private int compareObject(DSLMappingEntry item1,
                              DSLMappingEntry item2) {
        return item1.getMetaData().compareTo(item2.getMetaData());
    }

    /**
     * @return the sort criterion
     */
    public int getCriteria() {
        return criteria;
    }
}


/*
 * Copyright 2015 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 *      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.eclipse.webdav.dom;

import java.util.Enumeration;
import java.util.NoSuchElementException;
import org.eclipse.webdav.Policy;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * An element editor for the WebDAV supportedlock element. See RFC2518
 * section 13.11 for the element's definition.
 *

 * Note: This class/interface is part of an interim API that is still under
 * development and expected to change significantly before reaching stability.
 * It is being made available at this early stage to solicit feedback from pioneering
 * adopters on the understanding that any code that uses this API will almost
 * certainly be broken (repeatedly) as the API evolves.
 *

 *
 * @see LockEntry
 */
public class SupportedLock extends Property {
    /**
     * An ordered collection of the element names of the supportedlock
     * element's children.
     */
    protected static final String[] childNames = new String[] {"lockentry"}; //$NON-NLS-1$

    /**
     * Creates a new editor on the given WebDAV supportedlock element. The
     * element is assumed to be well formed.
     *
     * @param root a supportedlock element
     * @throws        MalformedElementException if there is reason to
     *                believe that the element is not well formed
     */
    public SupportedLock(Element root) throws MalformedElementException {
        super(root, "supportedlock"); //$NON-NLS-1$
    }

    /**
     * Creates a new lockentry and adds it to this supported lock. Returns
     * an editor on the new lockentry.
     *
     * @return an editor on a new lockentry for this supportedlock
     */
    public LockEntry addLockEntry() {

        Element lockentry = addChild(root, "lockentry", childNames, false); //$NON-NLS-1$
        Element locktype = appendChild(lockentry, "locktype"); //$NON-NLS-1$
        appendChild(locktype, "write"); //$NON-NLS-1$

        LockEntry result = null;
        try {
            result = new LockEntry(lockentry);
        } catch (MalformedElementException e) {
            Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
        }

        return result;
    }

    /**
     * Returns an Enumeration over this supportedlock's
     * LockEntrys.
     *
     * @return an Enumeration of LockEntrys
     * @throws MalformedElementException if there is reason to believe that
     *         this editor's underlying element is not well formed
     */
    public Enumeration getLockEntries() throws MalformedElementException {

        final Node firstLockEntry = getFirstChild(root, "lockentry"); //$NON-NLS-1$

        Enumeration e = new Enumeration() {
            Node currentLockEntry = firstLockEntry;

            public boolean hasMoreElements() {

                return currentLockEntry != null;
            }

            public Object nextElement() {

                if (!hasMoreElements())
                    throw new NoSuchElementException();

                LockEntry result = null;
                try {
                    result = new LockEntry((Element) currentLockEntry);
                } catch (MalformedElementException ex) {
                    Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
                }

                currentLockEntry = getTwin((Element) currentLockEntry, true);
                return result;
            }
        };

        return e;
    }
}


/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed 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.guvnor.tools.views;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;
import org.guvnor.tools.Activator;
import org.guvnor.tools.GuvnorRepository;
import org.guvnor.tools.Messages;
import org.guvnor.tools.GuvnorLocationManager.IRepositorySetListener;
import org.guvnor.tools.utils.GuvnorMetadataProps;
import org.guvnor.tools.utils.GuvnorMetadataUtils;
import org.guvnor.tools.utils.PlatformUtils;
import org.guvnor.tools.utils.webdav.IWebDavClient;
import org.guvnor.tools.utils.webdav.ResourceProperties;
import org.guvnor.tools.utils.webdav.WebDavClientFactory;
import org.guvnor.tools.utils.webdav.WebDavServerCache;
import org.guvnor.tools.views.model.TreeObject;
import org.guvnor.tools.views.model.TreeParent;
import org.guvnor.tools.wizards.NewRepLocationWizard;

/**
 * A view showing Guvnor structure in a tree.
 */
public class RepositoryView extends ViewPart {

    private TreeViewer viewer;
    private DrillDownAdapter drillDownAdapter;
    private Action deleteRepositoryLocAction;
    private Action addRepositoryLocAction;
    private Action doubleClickAction;
    private Action refreshAction;

    class NameSorter extends ViewerSorter {
    }

    public RepositoryView() {
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        drillDownAdapter = new DrillDownAdapter(viewer);
        viewer.setContentProvider(new RepositoryContentProvider());
        viewer.setLabelProvider(new RepositoryLabelProvider());
        viewer.setSorter(new NameSorter());
        viewer.setInput(viewer);
        makeActions();
        hookContextMenu();
        hookDoubleClickAction();
        contributeToActionBars();

        Activator.getLocationManager().addRepositorySetListener(new IRepositorySetListener() {
            public void repositorySetChanged(int type, List<GuvnorRepository> repList) {
                // TODO: Just creating an entirely new content provider.
                //       Someday might update this to have incremental changes
                //       to existing content provider.
                viewer.setContentProvider(new RepositoryContentProvider());
            }
        });

        super.getSite().setSelectionProvider(viewer);

        addDragDropSupport();
    }

    public void refresh() {
        viewer.refresh();
    }

    private void addDragDropSupport() {
        // TODO: Support drag and drop of directories
        Transfer[] transfers = new Transfer[] { FileTransfer.getInstance()};
        viewer.addDragSupport(DND.DROP_COPY, transfers, new DragSourceListener() {
            private TreeObject[] target;

            public void dragFinished(DragSourceEvent event) {
                target = null;
                event.doit = true;
            }
            public void dragSetData(DragSourceEvent event) {
                if (target == null) {
                    return;
                }
                try {
                    List<String> files = prepareFileTransfer(target);
                    String[] res = new String[files.size()];
                    files.toArray(res);
                    event.data = res;
                } catch (Exception e) {
                    // Note: we could catch a 401 (not authorized) WebDav error and retry,
                    // like we do when listing directories. But since we have to first list
                    // directories to get to files, and the act of listing directories authenticates
                    // for the server, currently we do not have a situation requiring authentication
                    // for specific files. This might be different in the future if the Guvnor security
                    // model changes, or users can directly connect to specific files.
                    Activator.getDefault().displayError(IStatus.ERROR, e.getMessage(), e, true);
                }
            }

            public void dragStart(DragSourceEvent event) {
                List<TreeObject> transferNodes = new ArrayList<TreeObject>();
                ISelection selection = viewer.getSelection();
                Object[] objs = ((IStructuredSelection)selection).toArray();
                for (int i = 0; i < objs.length; i++) {
                    if (objs[i] instanceof TreeObject
                        && ((TreeObject)objs[i]).getNodeType() == TreeObject.Type.RESOURCE) {
                        transferNodes.add((TreeObject)objs[i]);
                    }
                }
                if (transferNodes.size() > 0) {
                    event.doit = true;
                    target = new TreeObject[transferNodes.size()];
                    transferNodes.toArray(target);
                } else {
                    event.doit = false;
                }
            }
        });

        viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transfers, new ViewerDropAdapter(viewer) {

            private TreeParent targetNode;

            @Override
            public boolean performDrop(Object data) {
                if (targetNode == null) {
                    return false;
                }
                String[] items = (String[])data;

                boolean isvalid = validateInputResource(items);

                if(!isvalid) return false;

                String[] errors = processDrop(targetNode, items);
                if (errors.length != 0) {
                    StringBuilder msg = new StringBuilder();
                    for (int i = 0; i < errors.length; i++) {
                        msg.append(errors[i]);
                        msg.append("\r\n"); //$NON-NLS-1$
                    }
                    Activator.getDefault().
                        displayError(IStatus.ERROR, msg.toString(), new Exception(), true);
                }
                if (items.length != errors.length) {
                    // At least one item did not have an error,
                    // so refresh the views
                    PlatformUtils.updateDecoration();
                    PlatformUtils.refreshRepositoryView();
                }
                return items.length != errors.length;
            }

            @Override
            public boolean validateDrop(Object target,
                                       int operation,
                                       TransferData transferType) {
                // The drop target needs to be a directory
                if (target == null
                    || !(target instanceof TreeParent)) {
                    targetNode = null;
                    return false;
                }
                targetNode = (TreeParent)target;
                return true;
            }

        });
    }

    private boolean validateInputResource(String[] filenames){

        for(String filename : filenames){
            File file = new File(filename);
            String msg = "";
            if(!file.isFile()){
                msg = MessageFormat.format(Messages.getString("error.message.isfolder"), filename);
                MessageDialog.openError(null, "Problem Occurred", msg);
                return false;
            }

            String name = file.getName();
            if(!(name.indexOf(".") > 0)){
                msg = MessageFormat.format(Messages.getString("error.message.invalid.filename"), filename);
                MessageDialog.openError(null, "Problem Occurred", msg);
                return false;
            }
        }

        return true;
    }
    private String[] processDrop(TreeParent target, String[] items) {
        List<String> errors = new ArrayList<String>();

        for (int i = 0; i < items.length; i++) {
            IFile sourceFile = PlatformUtils.getResourceFromFSPath(items[i]);
            if (sourceFile != null) {
                try {
                    GuvnorMetadataProps md = GuvnorMetadataUtils.getGuvnorMetadata(sourceFile);
                    if (md == null) {
                        // The file is not already associated with Guvnor, so just add it
                        boolean res = GuvnorMetadataUtils.
                                        addResourceToGuvnor(target.getGuvnorRepository().getLocation(),
                                                           target.getFullPath(), sourceFile);
                        if (!res) {
                            errors.add(MessageFormat.format(Messages.getString("add.failure.exist"), //$NON-NLS-1$
                                                            new Object[] {sourceFile.getName(), target.getFullPath()}));
                        }
                    } else {
                        // Need to check if the drop location is the same as the Guvnor
                        // associated location. If so, then perform commit.
                        // If not, disallow the drop.
                        String itemPath = target.getFullPath() + sourceFile.getName();
                        if (itemPath.equals(md.getFullpath())) {
                            // If there are pending changes
                            if (!GuvnorMetadataUtils.isGuvnorResourceCurrent(sourceFile)) {
                                GuvnorMetadataUtils.commitFileChanges(sourceFile);
                            }
                        } else {
                            errors.add(MessageFormat.format(Messages.getString("already.guvnor.as"), //$NON-NLS-1$
                                                           new Object[] { items[i],
                                                                          md.getFullpath() }));
                        }
                    }
                } catch (Exception e) {
                    Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
                }
            } else {
                Activator.getDefault().
                    writeLog(IStatus.WARNING,
                            "Could not resolve: " + items[i],  //$NON-NLS-1$
                            new Exception());
            }
        }
        String[] res = new String[errors.size()];
        errors.toArray(res);
        return res;
    }

    private List<String> prepareFileTransfer(TreeObject[] nodes) throws Exception {
        List<String> res = new ArrayList<String>();
        for (int i = 0; i < nodes.length; i++) {
            String contents = getResourceContents(nodes[i]);
            IPath path = new Path(Activator.getDefault().getStateLocation().toOSString() +
                                  File.separator + "t" + //$NON-NLS-1$
                                  String.valueOf(System.currentTimeMillis()));
            if (!path.toFile().mkdir()) {
                throw new Exception("Could not create directory " + path.toOSString()); //$NON-NLS-1$
            }
            path.toFile().deleteOnExit();
            File transfer = new File(path + File.separator + nodes[i].getName());
            transfer.deleteOnExit();
            FileOutputStream fos = new FileOutputStream(transfer);
            PrintWriter writer = new PrintWriter(fos);
            writer.write(contents);
            writer.flush();
            writer.close();
            res.add(transfer.getAbsolutePath());

            IPath metaPath = GuvnorMetadataUtils.
                                createGuvnorMetadataLocation(path.toOSString());
            metaPath.toFile().deleteOnExit();
            File metaFile = GuvnorMetadataUtils.
                                getGuvnorMetadataFile(metaPath.toOSString(), nodes[i].getName());
            metaFile.deleteOnExit();
            GuvnorMetadataUtils.writeGuvnorMetadataProps(metaFile, getGuvnorMetadataProps(nodes[i]));
            res.add(metaFile.getAbsolutePath());
            // Put at least a 1ms gap in generated dir names above
            Thread.sleep(1, 0);
        }
        return res;
    }

    private GuvnorMetadataProps getGuvnorMetadataProps(TreeObject node) throws Exception {
        GuvnorRepository rep = node.getGuvnorRepository();
        IWebDavClient webdav = WebDavServerCache.getWebDavClient(rep.getLocation());
        if (webdav == null) {
            webdav = WebDavClientFactory.createClient(new URL(rep.getLocation()));
            WebDavServerCache.cacheWebDavClient(rep.getLocation(), webdav);
        }
        ResourceProperties props  = webdav.queryProperties(node.getFullPath());
        return new GuvnorMetadataProps(node.getName(),
                                      node.getGuvnorRepository().getLocation(),
                                      node.getFullPath(),
                                      props.getLastModifiedDate(),
                                      props.getRevision());
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                RepositoryView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalPullDown(IMenuManager manager) {
        manager.add(deleteRepositoryLocAction);
        manager.add(new Separator());
        manager.add(addRepositoryLocAction);
        manager.add(new Separator());
        manager.add(refreshAction);
    }

    private boolean shouldAddDeleteAction() {
        ISelection selection = viewer.getSelection();
        if (selection == null) {
            return false;
        }
        Object obj = ((IStructuredSelection)selection).getFirstElement();
        if (obj instanceof TreeParent) {
            return ((TreeParent)obj).getNodeType() == TreeObject.Type.REPOSITORY;
        } else {
            return false;
        }
    }

    private void fillContextMenu(IMenuManager manager) {
        if (shouldAddDeleteAction()) {
            manager.add(deleteRepositoryLocAction);
        }
        manager.add(refreshAction);
        drillDownAdapter.addNavigationActions(manager);
        // Other plug-ins can contribute there actions here
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    private void fillLocalToolBar(IToolBarManager manager) {
        manager.add(deleteRepositoryLocAction);
        manager.add(addRepositoryLocAction);
        manager.add(new Separator());
        drillDownAdapter.addNavigationActions(manager);
    }

    private void makeActions() {
        deleteRepositoryLocAction = new Action() {
            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection)selection).getFirstElement();
                if (obj instanceof TreeParent) {
                    GuvnorRepository rep = ((TreeParent)obj).getGuvnorRepository();
                    if (MessageDialog.openConfirm(RepositoryView.this.getSite().getShell(),
                                                 Messages.getString("remove.rep.dialog.caption"), //$NON-NLS-1$
                                                 MessageFormat.format(Messages.getString("remove.rep.dialog.msg"), //$NON-NLS-1$
                                                                     new Object[] { rep.getLocation() }))) {
                        Activator.getLocationManager().removeRepository(rep.getLocation());
                    }
                }
            }
        };
        deleteRepositoryLocAction.setText(Messages.getString("action.delete.rep")); //$NON-NLS-1$
        deleteRepositoryLocAction.setToolTipText(Messages.getString("action.delete.rep.desc")); //$NON-NLS-1$
        deleteRepositoryLocAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
            getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));

        addRepositoryLocAction = new Action() {
            public void run() {
                NewRepLocationWizard wiz = new NewRepLocationWizard();
                wiz.init(Activator.getDefault().getWorkbench(), null);
                WizardDialog dialog =
                    new WizardDialog(RepositoryView.this.getSite().getShell(), wiz);
                dialog.create();
                dialog.open();
            }
        };
        addRepositoryLocAction.setText(Messages.getString("action.add.rep")); //$NON-NLS-1$
        addRepositoryLocAction.setToolTipText(Messages.getString("action.add.rep.desc")); //$NON-NLS-1$
        addRepositoryLocAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
                getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD));

        doubleClickAction = new Action() {
            public void run() {
                ISelection selection = viewer.getSelection();
                Object obj = ((IStructuredSelection)selection).getFirstElement();
                if (obj instanceof TreeObject) {
                    doubleClick((TreeObject)obj);
                }
            }
        };

        refreshAction = new Action() {
            public void run() {
                ISelection selection = viewer.getSelection();
                if (selection instanceof IStructuredSelection) {
                    IStructuredSelection strucSel = (IStructuredSelection)selection;
                    if (!strucSel.isEmpty()) {
                        viewer.refresh(strucSel.getFirstElement());
                    }
                }
            }
        };
        refreshAction.setText(Messages.getString("action.refresh.rep")); //$NON-NLS-1$
        refreshAction.setToolTipText(Messages.getString("action.refresh.rep.desc")); //$NON-NLS-1$
        refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
                getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
    }

    private void hookDoubleClickAction() {
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                doubleClickAction.run();
            }
        });
    }

    private void doubleClick(TreeObject node) {
        if (node instanceof TreeParent) {
            if (viewer.getExpandedState(node)) {
                viewer.collapseToLevel(node, 1);
            } else {
                viewer.expandToLevel(node, 1);
            }
        } else {

            try {
                String contents = getResourceContents(node);
                PlatformUtils.openEditor(contents, node.getName());
            } catch (Exception e) {
                // Note: we could catch a 401 (not authorized) WebDav error and retry,
                // like we do when listing directories. But since we have to first list
                // directories to get to files, and the act of listing directories authenticates
                // for the server, currently we do not have a situation requiring authentication
                // for specific files. This might be different in the future if the Guvnor security
                // model changes, or users can directly connect to specific files.
                Activator.getDefault().displayError(IStatus.ERROR, e.getMessage(), e, true);
            }
        }
    }

    private String getResourceContents(TreeObject node) throws Exception {
        GuvnorRepository rep = node.getGuvnorRepository();
        IWebDavClient webdav = WebDavServerCache.getWebDavClient(rep.getLocation());
        if (webdav == null) {
            webdav = WebDavClientFactory.createClient(new URL(rep.getLocation()));
            WebDavServerCache.cacheWebDavClient(rep.getLocation(), webdav);
        }
        String res = webdav.getResourceContents(node.getFullPath());
        return res;
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }
}


/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed 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.drools.eclipse.editors.rete.model;

import java.util.ArrayList;
import java.util.List;

import org.drools.eclipse.reteoo.BaseVertex;

/**
 * Rete graph containing a set of vertices that form the graph itself.
 */
public class ReteGraph extends ModelElement {

    /** Property ID to use when a child is added to this diagram. */
    public static final String PROP_CHILD_ADDED   = "ReteGraph.ChildAdded";

    /** Property ID to use when a child is removed from this diagram. */
    public static final String PROP_CHILD_REMOVED = "ReteGraph.ChildRemoved";

    private List<BaseVertex>     vertices           = new ArrayList<BaseVertex>();

    /**
     * Add new BaseVertex to the graph
     *
     * @param vertex
     *
     * @return true, if vertex was added, false otherwise
     */
    public boolean addChild(BaseVertex vertex) {
        if ( vertex != null && vertices.add( vertex ) ) {
            firePropertyChange( PROP_CHILD_ADDED,
                                null,
                                vertex );
            return true;
        }
        return false;
    }

    /**
     * Return all Vertices in this graph
     */
    public List<BaseVertex> getChildren() {
        return vertices;
    }

    /**
     * Remove a vertex from this graph
     *
     * @param vertex vertex to be removed
     * @return true, if the vertex removal succeeded, false otherwise
     */
    public boolean removeChild(BaseVertex vertex) {
        if ( vertex != null && vertices.remove( vertex ) ) {
            firePropertyChange( PROP_CHILD_REMOVED,
                                null,
                                vertex );
            return true;
        }
        return false;
    }

    /**
     * Removes all vertices from graph.
     */
    public void removeAll() {
        while ( vertices.size() > 0 ) {
            removeChild( ((BaseVertex) vertices.get( 0 )) );
        }
    }

    public void addAll(List<BaseVertex> children) {
        for (BaseVertex vertex : children) {
            addChild( vertex );
        }
    }

}


/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed 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.drools.eclipse;

import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.drools.compiler.builder.impl.KnowledgeBuilderConfigurationImpl;
import org.drools.compiler.builder.impl.KnowledgeBuilderImpl;
import org.drools.compiler.compiler.BaseKnowledgeBuilderResultImpl;
import org.drools.compiler.compiler.DrlParser;
import org.drools.compiler.compiler.DroolsError;
import org.drools.compiler.compiler.DroolsParserException;
import org.drools.compiler.compiler.PackageRegistry;
import org.drools.compiler.lang.descr.AttributeDescr;
import org.drools.compiler.lang.descr.BaseDescr;
import org.drools.compiler.lang.descr.EnumDeclarationDescr;
import org.drools.compiler.lang.descr.FunctionDescr;
import org.drools.compiler.lang.descr.FunctionImportDescr;
import org.drools.compiler.lang.descr.GlobalDescr;
import org.drools.compiler.lang.descr.ImportDescr;
import org.drools.compiler.lang.descr.PackageDescr;
import org.drools.compiler.lang.descr.RuleDescr;
import org.drools.compiler.lang.descr.TypeDeclarationDescr;
import org.drools.compiler.rule.builder.dialect.java.JavaDialectConfiguration;
import org.drools.core.definitions.impl.KnowledgePackageImpl;
import org.drools.core.util.StringUtils;
import org.drools.core.xml.SemanticModules;
import org.drools.eclipse.DRLInfo.FunctionInfo;
import org.drools.eclipse.DRLInfo.RuleInfo;
import org.drools.eclipse.builder.DroolsBuilder;
import org.drools.eclipse.builder.ResourceDescr;
import org.drools.eclipse.builder.Util;
import org.drools.eclipse.dsl.editor.DSLAdapter;
import org.drools.eclipse.editors.AbstractRuleEditor;
import org.drools.eclipse.preferences.IDroolsConstants;
import org.drools.eclipse.util.ProjectClassLoader;
import org.drools.template.parser.DecisionTableParseException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.FormColors;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.jbpm.bpmn2.xml.BPMNDISemanticModule;
import org.jbpm.bpmn2.xml.BPMNExtensionsSemanticModule;
import org.jbpm.bpmn2.xml.BPMNSemanticModule;
import org.jbpm.compiler.ProcessBuilderImpl;
import org.jbpm.compiler.xml.ProcessSemanticModule;
import org.jbpm.compiler.xml.XmlProcessReader;
import org.jbpm.process.core.Process;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.node.RuleSetNode;
import org.kie.api.definition.process.Node;
import org.kie.api.io.Resource;
import org.kie.internal.builder.CompositeKnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderConfiguration;
import org.kie.internal.builder.KnowledgeBuilderError;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.osgi.framework.BundleContext;

/**
 * The main plugin class to be used in the desktop.
 */
public class DroolsEclipsePlugin extends AbstractUIPlugin {

    public static final int             INTERNAL_ERROR             = 120;
    public static final String          PLUGIN_ID                  = "org.drools.eclipse";
    public static final String          BUILD_RESULT_PACKAGE       = "Package";
    public static final String          BUILD_RESULT_PACKAGE_DESCR = "PackageDescr";

    //The shared instance.
    private static DroolsEclipsePlugin  plugin;
    //Resource bundle.
    private ResourceBundle              resourceBundle;
    private Map<String, Color>          colors                     = new HashMap<String, Color>();
    private Map<IResource, DRLInfo>     parsedRules                = new HashMap<IResource, DRLInfo>();
    private Map<IResource, DRLInfo>     compiledRules              = new HashMap<IResource, DRLInfo>();
    private Map<String, RuleInfo>       ruleInfoByClassNameMap     = new HashMap<String, RuleInfo>();
    private Map<String, FunctionInfo>   functionInfoByClassNameMap = new HashMap<String, FunctionInfo>();
    private Map<IResource, ProcessInfo> processInfos               = new HashMap<IResource, ProcessInfo>();
    private Map<String, ProcessInfo>    processInfosById           = new HashMap<String, ProcessInfo>();
    private boolean                     useCachePreference;

    private FormColors                  ruleBuilderFormColors;

    private boolean 					forceFullBuild;

    /**
     * The constructor.
     */
    public DroolsEclipsePlugin() {
        super();
        plugin = this;
    }

    /**
     * This method is called upon plug-in activation
     */
	public void start(BundleContext context) throws Exception {
        super.start( context );
        IPreferenceStore preferenceStore = getPreferenceStore();
        useCachePreference = preferenceStore.getBoolean( IDroolsConstants.CACHE_PARSED_RULES );
        preferenceStore.addPropertyChangeListener( new IPropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if ( IDroolsConstants.CACHE_PARSED_RULES.equals( event.getProperty() ) ) {
                    useCachePreference = ((Boolean) event.getNewValue()).booleanValue();
                    if ( !useCachePreference ) {
                        clearCache();
                    }
                }
            }
        } );
    }

    public static BundleContext getContext() {
    	return plugin.getBundle().getBundleContext();
    }

    public void clearCache() {
        parsedRules.clear();
        compiledRules.clear();
        ruleInfoByClassNameMap.clear();
        functionInfoByClassNameMap.clear();
        processInfos.clear();
        processInfosById = null;
    }

    /**
     * This method is called when the plug-in is stopped
     */
    public void stop(BundleContext context) throws Exception {
        super.stop( context );
        plugin = null;
        resourceBundle = null;
        parsedRules = null;
        compiledRules = null;
        processInfos = null;
        processInfosById = null;
        for (Color color: colors.values()) {
            color.dispose();
        }
    }

    /**
     * Returns the shared instance.
     */
    public static DroolsEclipsePlugin getDefault() {
        return plugin;
    }

    /**
     * Returns the string from the plugin's resource bundle,
     * or 'key' if not found.
     */
    public static String getResourceString(String key) {
        ResourceBundle bundle = DroolsEclipsePlugin.getDefault().getResourceBundle();
        try {
            return (bundle != null) ? bundle.getString( key ) : key;
        } catch ( MissingResourceException e ) {
            return key;
        }
    }

    /**
     * Returns the plugin's resource bundle,
     */
    public ResourceBundle getResourceBundle() {
        try {
            if ( resourceBundle == null ) resourceBundle = ResourceBundle.getBundle( "droolsIDE.DroolsIDEPluginResources" );
        } catch ( MissingResourceException x ) {
            resourceBundle = null;
        }
        return resourceBundle;
    }

    /**
     * Returns an image descriptor for the image file at the given
     * plug-in relative path.
     * Uses the plug ins image registry to "cache" it.
     *
     * @param path the path
     * @return the image descriptor
     */
    public static ImageDescriptor getImageDescriptor(String path) {

        DroolsEclipsePlugin plugin = getDefault();
        ImageRegistry reg = plugin.getImageRegistry();
        ImageDescriptor des = reg.getDescriptor( path );
        if ( des == null ) {
            des = AbstractUIPlugin.imageDescriptorFromPlugin( "org.drools.eclipse",
                                                              path );
            reg.put( path,
                     des );
        }
        return des;
    }

    public static String getUniqueIdentifier() {
        if ( getDefault() == null ) {
            return PLUGIN_ID;
        }
        return getDefault().getBundle().getSymbolicName();
    }

    public static void log(Throwable t) {
        Throwable top = t;
        if ( t instanceof DebugException ) {
            DebugException de = (DebugException) t;
            IStatus status = de.getStatus();
            if ( status.getException() != null ) {
                top = status.getException();
            }
        }
        log( new Status( IStatus.ERROR,
                         getUniqueIdentifier(),
                         INTERNAL_ERROR,
                         "Internal error in Drools Plugin: ",
                         top ) );
    }

    public static void log(IStatus status) {
        getDefault().getLog().log( status );
    }

    public Color getColor(String type) {
        return (Color) colors.get( type );
    }

    public void setColor(String type,
                         Color color) {
        colors.put( type,
                    color );
    }

    protected void initializeDefaultPreferences(IPreferenceStore store) {
        store.setDefault( IDroolsConstants.BUILD_ALL,
                          false );
        store.setDefault( IDroolsConstants.CROSS_BUILD,
        				  false );
        store.setDefault( IDroolsConstants.EDITOR_FOLDING,
                          true );
        store.setDefault( IDroolsConstants.CACHE_PARSED_RULES,
                          true );
        store.setDefault( IDroolsConstants.DSL_RULE_EDITOR_COMPLETION_FULL_SENTENCES,
                          true );
        store.setDefault( IDroolsConstants.SKIN,
                          "BPMN2" );
        store.setDefault( IDroolsConstants.ALLOW_NODE_CUSTOMIZATION,
                          false );
        store.setDefault( IDroolsConstants.INTERNAL_API,
                          2 );
        store.setDefault( IDroolsConstants.FLOW_NODES,
                          "1111111111111" );
    }

    public List<DRLInfo> parseResources(List<ResourceDescr> resources) {
    	List<ResourceDescr> toBeCompiled = new ArrayList<ResourceDescr>();
    	List<DRLInfo> infos = new ArrayList<DRLInfo>();

    	for (ResourceDescr resourceDescr : resources) {
	        DRLInfo result = getExistingInfoForResource(resourceDescr.getResource(), true);
	        if ( result != null ) {
	        	infos.add(result);
	        } else {
	        	toBeCompiled.add(resourceDescr);
	        }
    	}

    	infos.addAll(buildResources(toBeCompiled));
    	return infos;
    }

    private List<DRLInfo> buildResources(List<ResourceDescr> resources) {
    	if (resources.isEmpty()) return Collections.emptyList();

        ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();

        try {
        	Map<Resource, ResourceDescr> resourceMap = new HashMap<Resource, ResourceDescr>();
        	KnowledgeBuilder kbuilder = compositeBuild(resources, resourceMap);

        	KnowledgeBuilderImpl kBuilder = ((KnowledgeBuilderImpl)kbuilder);
            Map<IResource, DRLInfo> infoMap = collectDRLInfo(resourceMap, kBuilder);
    		collectErrors(resourceMap, kbuilder, kBuilder, infoMap);

    		for (DRLInfo drlInfo : infoMap.values()) {
                for ( RuleInfo ruleInfo : drlInfo.getRuleInfos() ) {
                    ruleInfoByClassNameMap.put( ruleInfo.getClassName(), ruleInfo );
                }
                for ( FunctionInfo functionInfo : drlInfo.getFunctionInfos() ) {
                    functionInfoByClassNameMap.put( functionInfo.getClassName(), functionInfo );
                }
    		}

    		compiledRules = infoMap;

    		return new ArrayList<DRLInfo>(infoMap.values());
        } catch ( CoreException e ) {
            log( e );
        } finally {
            Thread.currentThread().setContextClassLoader( oldLoader );
        }

        return Collections.emptyList();
    }

	private KnowledgeBuilder compositeBuild(List<ResourceDescr> resources, Map<Resource, ResourceDescr> resourceMap) throws CoreException {
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(getBuilderConfiguration(resources));
		CompositeKnowledgeBuilder compositeKBuilder = kbuilder.batch();
		for (ResourceDescr resourceDescr : resources) {
			Resource resource = resourceDescr.getContentAsDroolsResource();
			resourceMap.put(resource, resourceDescr);
			compositeKBuilder.add(resource, resourceDescr.getType());
		}
		try {
			compositeKBuilder.build();
		} catch (DecisionTableParseException dtpe) {
			// swallow
		}
		return kbuilder;
	}

	private Map<IResource, DRLInfo> collectDRLInfo( Map<Resource, ResourceDescr> resourceMap,
			                                        KnowledgeBuilderImpl kBuilder) {
		Map<IResource, DRLInfo> infoMap = new HashMap<IResource, DRLInfo>();

		for (Map.Entry<Resource, PackageDescr> entry : groupPackageDescrByResource(kBuilder).entrySet()) {
			ResourceDescr resourceDescr = resourceMap.get(entry.getKey());
			if (resourceDescr == null) {
				continue;
			}
			PackageDescr packageDescr = entry.getValue();

			DRLInfo info = new DRLInfo( resourceDescr.getSourcePathName(),
		            packageDescr,
		            new ArrayList<BaseKnowledgeBuilderResultImpl>(),
		            kBuilder.getPackageRegistry(packageDescr.getNamespace()).getPackage(),
		            new DroolsError[0],
		            kBuilder.getPackageRegistry( packageDescr.getNamespace() ).getDialectCompiletimeRegistry() );

			info.setResource(resourceDescr.getResource());
			infoMap.put(resourceDescr.getResource(), info);
		}
		return infoMap;
	}

	private void collectErrors( Map<Resource, ResourceDescr> resourceMap,
								KnowledgeBuilder kbuilder,
								KnowledgeBuilderImpl kBuilder,
								Map<IResource, DRLInfo> infoMap) {
		for (KnowledgeBuilderError error : (Collection<KnowledgeBuilderError>)kbuilder.getErrors()) {
			if (!(error instanceof DroolsError)) {
				continue;
			}
			Resource resource = error.getResource();
			if (resource == null) {
				continue;
			}
			ResourceDescr resourceDescr = resourceMap.get(resource);

			final DroolsError droolsError = (DroolsError)error;
			String pkgName = droolsError.getNamespace();
			List<PackageDescr> packageDescrs = kBuilder.getPackageDescrs(pkgName);
			if (packageDescrs == null || packageDescrs.isEmpty()) {
				continue;
			}
			PackageDescr packageDescr = packageDescrs.get(0);

			DRLInfo info = infoMap.get(resourceDescr.getResource());
			if (info == null) {
				info = new DRLInfo( resourceDescr.getResource().getName(),
		                packageDescr,
		                new ArrayList<BaseKnowledgeBuilderResultImpl>() {{
		                	add(droolsError);
		                }},
		                kBuilder.getPackageRegistry( packageDescr.getNamespace() ).getDialectCompiletimeRegistry() );
				info.setResource(resourceDescr.getResource());
				infoMap.put(resourceDescr.getResource(), info);
			} else {
				info.addError(droolsError);
			}
		}
	}

    private Map<Resource, PackageDescr> groupPackageDescrByResource(KnowledgeBuilderImpl kBuilder) {
    	Map<Resource, PackageDescr> map = new HashMap<Resource, PackageDescr>();
    	for (String pkgName : kBuilder.getPackageNames()) {
    		for (PackageDescr pkgDescr : kBuilder.getPackageDescrs(pkgName)) {
    			for (ImportDescr importDescr : pkgDescr.getImports()) {
    				getPkgDescr(map, importDescr, pkgName).addImport(importDescr);
    			}
    			for (FunctionImportDescr function : pkgDescr.getFunctionImports()) {
    				getPkgDescr(map, function, pkgName).addFunctionImport(function);
    			}
    			for (AttributeDescr attribute : pkgDescr.getAttributes()) {
    				getPkgDescr(map, attribute, pkgName).addAttribute(attribute);
    			}
    			for (GlobalDescr global : pkgDescr.getGlobals()) {
    				getPkgDescr(map, global, pkgName).addGlobal(global);
    			}
    			for (FunctionDescr function : pkgDescr.getFunctions()) {
    				getPkgDescr(map, function, pkgName).addFunction(function);
    			}
    			for (TypeDeclarationDescr type : pkgDescr.getTypeDeclarations()) {
    				getPkgDescr(map, type, pkgName).addTypeDeclaration(type);
    			}
    			for (RuleDescr rule : pkgDescr.getRules()) {
    				getPkgDescr(map, rule, pkgName).addRule(rule);
    			}
    			for (EnumDeclarationDescr enumDescr : pkgDescr.getEnumDeclarations()) {
    				getPkgDescr(map, enumDescr, pkgName).addEnumDeclaration(enumDescr);
    			}
    		}
    	}
    	return map;
    }

    private PackageDescr getPkgDescr(Map<Resource, PackageDescr> map, BaseDescr descr, String pkgName) {
    	Resource resource = descr.getResource();
		PackageDescr resourceDescr = map.get(resource);
		if (resourceDescr == null) {
			resourceDescr = new PackageDescr();
			resourceDescr.setNamespace(pkgName);
			map.put(resource, resourceDescr);
		}
		return resourceDescr;
    }

    private KnowledgeBuilderConfiguration getBuilderConfiguration(List<ResourceDescr> resources) throws CoreException {
        ClassLoader newLoader = DroolsBuilder.class.getClassLoader();
        IResource firstResource = resources.get(0).getResource();
        String level = null;
        if ( firstResource.getProject().getNature( "org.eclipse.jdt.core.javanature" ) != null ) {
            IJavaProject project = JavaCore.create( firstResource.getProject() );
            newLoader = ProjectClassLoader.getProjectClassLoader( project );
            level = project.getOption( JavaCore.COMPILER_COMPLIANCE, true );
        }

        Thread.currentThread().setContextClassLoader( newLoader );
        KnowledgeBuilderConfigurationImpl builderConfiguration = new KnowledgeBuilderConfigurationImpl();
        if ( level != null ) {
            JavaDialectConfiguration javaConf = (JavaDialectConfiguration) builderConfiguration.getDialectConfiguration( "java" );
            javaConf.setJavaLanguageLevel( level );
        }
        return builderConfiguration;
    }

    public DRLInfo parseResource(IResource resource,
                                 boolean compile) throws DroolsParserException {
        DRLInfo result = getExistingInfoForResource(resource, compile);
        if ( result != null ) {
            return result;
        }
        return generateParsedResource( resource,
                                       compile );
    }

    private DRLInfo getExistingInfoForResource(IResource resource, boolean compile) {
        DRLInfo result = (DRLInfo) compiledRules.get( resource );
        if ( result == null && !compile ) {
            result = (DRLInfo) parsedRules.get( resource );
        }
        return result;
    }

    public DRLInfo parseResource(AbstractRuleEditor editor,
                                 boolean useUnsavedContent,
                                 boolean compile) throws DroolsParserException {
        IResource resource = editor.getResource();
        if ( !editor.isDirty() || !useUnsavedContent ) {
            DRLInfo result = (DRLInfo) compiledRules.get( resource );
            if ( result == null && !compile ) {
                result = (DRLInfo) parsedRules.get( resource );
            }
            if ( result != null ) {
                return result;
            }
        }
        if ( !editor.isDirty() ) {
            return generateParsedResource( editor.getContent(),
                                           resource,
                                           true,
                                           compile );
        }
        // TODO: can we cache result when using unsaved content as well?
        return generateParsedResource( editor.getContent(),
                                       resource,
                                       !useUnsavedContent,
                                       compile );
    }

    public DRLInfo parseXLSResource(String content,
                                    IResource resource) throws DroolsParserException {
        DRLInfo result = (DRLInfo) compiledRules.get( resource );
        if ( result != null ) {
            return result;
        }
        return generateParsedResource( content,
                                       resource,
                                       false,
                                       true );
    }

    public DRLInfo parseBRLResource(String content,
                                    IResource resource) throws DroolsParserException {
        DRLInfo result = (DRLInfo) compiledRules.get( resource );
        if ( result != null ) {
            return result;
        }
        return generateParsedResource( content,
                                       resource,
                                       false,
                                       true );
    }

    public DRLInfo parseGDSTResource(String content, IResource resource) throws DroolsParserException {
        DRLInfo result = (DRLInfo) compiledRules.get(resource);
        if (result != null) {
            return result;
        }
        return generateParsedResource(content, resource, false, true);
    }

    public void invalidateResource(IResource resource) {
        DRLInfo cached = (DRLInfo) compiledRules.remove( resource );
        if ( cached != null ) {
            RuleInfo[] ruleInfos = cached.getRuleInfos();
            for ( int i = 0; i < ruleInfos.length; i++ ) {
                ruleInfoByClassNameMap.remove( ruleInfos[i].getClassName() );
            }
            FunctionInfo[] functionInfos = cached.getFunctionInfos();
            for ( int i = 0; i < functionInfos.length; i++ ) {
                functionInfoByClassNameMap.remove( functionInfos[i].getClassName() );
            }
        }
        parsedRules.remove( resource );
        ProcessInfo processInfo = processInfos.remove( resource );
        if ( processInfo != null ) {
            processInfosById.remove( processInfo.getProcessId() );
        }
    }

    private DRLInfo generateParsedResource(IResource resource,
                                           boolean compile) throws DroolsParserException {
        if ( resource instanceof IFile ) {
            IFile file = (IFile) resource;
            try {
                String content = new String( Util.getResourceContentsAsCharArray( file ) );
                return generateParsedResource( content,
                                               file,
                                               true,
                                               compile );
            } catch ( CoreException e ) {
                log( e );
            }
        }
        return null;
    }

    public DRLInfo generateParsedResource(String content,
                                          IResource resource,
                                          boolean useCache,
                                          boolean compile) throws DroolsParserException {
        useCache = useCache && useCachePreference;
        try {
            ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
            ClassLoader newLoader = DroolsBuilder.class.getClassLoader();
            String level = null;
            // resource could be null when opening a read-only remote file
            if ( resource != null && resource.getProject().getNature( "org.eclipse.jdt.core.javanature" ) != null ) {
                IJavaProject project = JavaCore.create( resource.getProject() );
                newLoader = ProjectClassLoader.getProjectClassLoader( project );
                level = project.getOption( JavaCore.COMPILER_COMPLIANCE, true );
            }
            try {
                Thread.currentThread().setContextClassLoader( newLoader );
                KnowledgeBuilderConfigurationImpl builder_configuration = new KnowledgeBuilderConfigurationImpl(newLoader);
                if ( level != null ) {
                    JavaDialectConfiguration javaConf = (JavaDialectConfiguration) builder_configuration.getDialectConfiguration( "java" );
                    javaConf.setJavaLanguageLevel( level );
                }

                // first parse the source
                PackageDescr packageDescr = null;
                List<BaseKnowledgeBuilderResultImpl> parserErrors = null;
                if ( useCache && resource != null) {
                    DRLInfo cachedDrlInfo = (DRLInfo) parsedRules.get( resource );
                    if ( cachedDrlInfo != null ) {
                        packageDescr = cachedDrlInfo.getPackageDescr();
                        parserErrors = cachedDrlInfo.getParserErrors();
                    }
                }

                DrlParser parser = new DrlParser();
                if ( packageDescr == null ) {
                    Reader dslReader = DSLAdapter.getDSLContent( content, resource );
                    if ( dslReader != null ) {
                        packageDescr = parser.parse( true, content, dslReader );
                    } else {
                        packageDescr = parser.parse( true, content );
                    }
                    parserErrors = new ArrayList<BaseKnowledgeBuilderResultImpl>();
                    parserErrors.addAll(parser.getErrors());
                }
                KnowledgeBuilderImpl builder = new KnowledgeBuilderImpl( builder_configuration );
                DRLInfo result = null;
                // compile parsed rules if necessary
                if ( packageDescr != null && compile && !parser.hasErrors()) {
                    // check whether a .package file exists and add it
                    if ( resource != null && resource.getParent() != null ) {
                        MyResourceVisitor visitor = new MyResourceVisitor();
                        resource.getParent().accept( visitor,
                                                     IResource.DEPTH_ONE,
                                                     IResource.NONE );
                        IResource packageDef = visitor.getPackageDef();
                        if ( packageDef != null ) {
                            PackageDescr desc = parseResource( packageDef,
                                                               false ).getPackageDescr();
                            if (desc != null){
                                builder.addPackage( desc);
                            }
                        }
                    }

                    builder.addPackage( packageDescr );

                    // make sure the namespace is set, use default if necessary, as this is used to build the DRLInfo
                    if ( StringUtils.isEmpty( packageDescr.getNamespace() ) ) {
                        packageDescr.setNamespace( builder.getBuilderConfiguration().getDefaultPackageName() );
                    }

                    result = new DRLInfo( resource == null ? "" : resource.getProjectRelativePath().toString(),
                                          packageDescr,
                                          parserErrors,
                                          builder.getPackageRegistry(packageDescr.getNamespace()).getPackage(),
                                          builder.getErrors().getErrors(),
                                          builder.getPackageRegistry( packageDescr.getNamespace() ).getDialectCompiletimeRegistry() );
                } else {
                    result = new DRLInfo( resource == null ? "" : resource.getProjectRelativePath().toString(),
                                          packageDescr,
                                          parserErrors,
                                          new PackageRegistry(newLoader, builder.getBuilderConfiguration(), new KnowledgePackageImpl("")).getDialectCompiletimeRegistry() );
                }

                // cache result
                if ( useCache && resource != null) {
                    if ( compile && !parser.hasErrors() ) {
                        parsedRules.remove( resource );
                        compiledRules.put( resource,
                                           result );
                        RuleInfo[] ruleInfos = result.getRuleInfos();
                        for ( int i = 0; i < ruleInfos.length; i++ ) {
                            ruleInfoByClassNameMap.put( ruleInfos[i].getClassName(),
                                                        ruleInfos[i] );
                        }
                        FunctionInfo[] functionInfos = result.getFunctionInfos();
                        for ( int i = 0; i < functionInfos.length; i++ ) {
                            functionInfoByClassNameMap.put( functionInfos[i].getClassName(),
                                                            functionInfos[i] );
                        }
                    } else {
                        parsedRules.put( resource,
                                         result );
                    }
                }
                return result;
            } finally {
                Thread.currentThread().setContextClassLoader( oldLoader );
            }
        } catch ( CoreException e ) {
            log( e );
        }
        return null;
    }

    public RuleInfo getRuleInfoByClass(String ruleClassName) {
        return (RuleInfo) ruleInfoByClassNameMap.get( ruleClassName );
    }

    public FunctionInfo getFunctionInfoByClass(String functionClassName) {
        return (FunctionInfo) functionInfoByClassNameMap.get( functionClassName );
    }

    public ProcessInfo parseProcess(String input,
                                    IResource resource) throws Exception {
        try {
            ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
            ClassLoader newLoader = this.getClass().getClassLoader();
            String level = null;
            if ( resource.getProject().getNature( "org.eclipse.jdt.core.javanature" ) != null ) {
                IJavaProject project = JavaCore.create( resource.getProject() );
                newLoader = ProjectClassLoader.getProjectClassLoader( project );
                level = project.getOption( JavaCore.COMPILER_COMPLIANCE,
                                           true );
            }
            try {
                Thread.currentThread().setContextClassLoader( newLoader );
                KnowledgeBuilderConfigurationImpl configuration = new KnowledgeBuilderConfigurationImpl();
                if ( level != null ) {
                    JavaDialectConfiguration javaConf = (JavaDialectConfiguration) configuration.getDialectConfiguration( "java" );
                    javaConf.setJavaLanguageLevel( level );
                }

                SemanticModules modules = configuration.getSemanticModules();
                modules.addSemanticModule( new BPMNSemanticModule() );
                modules.addSemanticModule( new BPMNDISemanticModule() );
                modules.addSemanticModule( new BPMNExtensionsSemanticModule() );
                modules.addSemanticModule( new ProcessSemanticModule() );

                XmlProcessReader xmlReader = new XmlProcessReader( modules, Thread.currentThread().getContextClassLoader() );
                List<org.kie.api.definition.process.Process> processes =
                    (List<org.kie.api.definition.process.Process>) xmlReader.read( new StringReader( input ) );
                if (processes != null) {
                    for (org.kie.api.definition.process.Process process: processes) {
                        if ( process != null ) {
                            return parseProcess( (Process) process,
                                                 resource,
                                                 configuration );
                        } else {
                            throw new IllegalArgumentException( "Could not parse process " + resource );
                        }
                    }
                }
            } finally {
                Thread.currentThread().setContextClassLoader( oldLoader );
            }
        } catch ( Exception e ) {
            log( e );
            throw e;
        }
        return null;
    }

    public ProcessInfo getProcessInfo(String processId) {
        return processInfosById.get( processId );
    }

    public Map<ProcessInfo,List<RuleSetNode>> getRuleSetNodeByFlowGroup(String flowGroup) {
    	Map<ProcessInfo,List<RuleSetNode>> result = new HashMap<ProcessInfo,List<RuleSetNode>>();
    	for (ProcessInfo processInfo : processInfosById.values()) {
    		Node[] nodes = ((RuleFlowProcess)processInfo.getProcess()).getNodes();
    		for (int i = 0; i < nodes.length; i++) {
    			if(nodes[i] instanceof RuleSetNode)
    				if(flowGroup.equals(((RuleSetNode)nodes[i]).getRuleFlowGroup())) {
    					if(!result.containsKey(processInfo))
    						result.put(processInfo, new ArrayList<RuleSetNode>());
    					result.get(processInfo).add((RuleSetNode) nodes[i]);
    				}

			}
		}
        return result;
    }

    public IResource findProcessResource(String processId) {
        if (processId == null) {
            return null;
        }
        for (Map.Entry<IResource, ProcessInfo> entry: processInfos.entrySet()) {
            if (processId.equals(entry.getValue().getProcessId())) {
                return entry.getKey();
            }
        }
        return null;
    }

    public ProcessInfo parseProcess(Process process,
                                    IResource resource,
                                    KnowledgeBuilderConfigurationImpl config) {
    	KnowledgeBuilderImpl packageBuilder = new KnowledgeBuilderImpl( config );
        ProcessBuilderImpl processBuilder = new ProcessBuilderImpl( packageBuilder );
        processBuilder.buildProcess( process, ResourceFactory.newUrlResource(
            "file://" + resource.getLocation().toString() ) );
        ProcessInfo processInfo = new ProcessInfo( process.getId(),
                                                   process );
        List<BaseKnowledgeBuilderResultImpl> errors = new ArrayList<BaseKnowledgeBuilderResultImpl>();
        errors.addAll( processBuilder.getErrors() );
        errors.addAll( Arrays.asList( packageBuilder.getErrors().getErrors() ) );
        processInfo.setErrors( errors );
        if ( useCachePreference ) {
            processInfos.put( resource,
                              processInfo );
            processInfosById.put( process.getId(),
                                  processInfo );
        }
        return processInfo;
    }

    /**
     * Form Colors, default colors for now.
     *
     * @param display
     * @return
     */
    public FormColors getRuleBuilderFormColors(Display display) {
        if ( ruleBuilderFormColors == null ) {
            ruleBuilderFormColors = new FormColors( display );
            ruleBuilderFormColors.markShared();
        }
        return ruleBuilderFormColors;
    }

    public boolean resetForceFullBuild() {
    	boolean isFullBuild = forceFullBuild;
    	forceFullBuild = false;
		return isFullBuild;
	}

	public void setForceFullBuild() {
		forceFullBuild = true;
	}

	private class MyResourceVisitor
        implements
        IResourceVisitor {
        private IResource packageDef;

        public boolean visit(IResource resource) throws CoreException {
            if ( "package".equals( resource.getFileExtension() ) ) {
                packageDef = resource;
            }
            return true;
        }

        public IResource getPackageDef() {
            return packageDef;
        }
    }
}


/*
 * Copyright 2015 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 *      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.eclipse.webdav.internal.kernel.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * A generic date and time object. It uses UTC as the timezone and US as the locale.
 */

public class DateTime {
    protected SimpleDateFormat dateFormat;
    protected long dateTime;

    protected static final String RFC_1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss 'GMT'"; //$NON-NLS-1$
    protected static final String RFC_850_PATTERN = "E, dd-MMM-yyyy HH:mm:ss 'GMT'"; //$NON-NLS-1$
    protected static final String ASCTIME_PATTERN = "EEE MMM dd HH:mm:ss yyyy"; //$NON-NLS-1$
    protected static final String ISO_8601_UTC_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
    protected static final String ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ssz"; //$NON-NLS-1$
    protected static final String ISO_8601_UTC_MILLIS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; //$NON-NLS-1$
    protected static final String ISO_8601_MILLIS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSz"; //$NON-NLS-1$

    public DateTime() {
        this(0);
    }

    /**
     * Starts this object from a java long format (milliseconds).
     */
    public DateTime(long date) {
        setDateTime(date);
        dateFormat = new SimpleDateFormat();
        dateFormat.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US)); //$NON-NLS-1$
    }

    public boolean after(DateTime other) {
        return getDateTime() > other.getDateTime();
    }

    public boolean before(DateTime other) {
        return getDateTime() < other.getDateTime();
    }

    public boolean equals(DateTime other) {
        return getDateTime() == other.getDateTime();
    }

    /**
     * Milliseconds since 1 January 1970 0:00 UTC.
     */
    public long getDateTime() {
        return dateTime;
    }

    public int getMilliseconds() {
        return (int) (getDateTime() % 1000);
    }

    /**
     * Sets the date and time from a java long format (milliseconds).
     */
    public void setDateTime(long dateTime) {
        this.dateTime = dateTime;
    }

    /**
     * Do nothing if date format is not supported
     */
    public void setDateTime(String date) {
        String[] patterns = {RFC_1123_PATTERN, ISO_8601_UTC_PATTERN, ISO_8601_UTC_MILLIS_PATTERN, ISO_8601_PATTERN, ISO_8601_MILLIS_PATTERN, RFC_850_PATTERN, ASCTIME_PATTERN};
        for (int i = 0; i < patterns.length; i++) {
            if (setDateTime(date, patterns[i]))
                break;
        }
    }

    /**
     * Do nothing if date format is not supported.
     */
    protected boolean setDateTime(String date, String pattern) {
        boolean dateChanged = true;
        dateFormat.applyPattern(pattern);
        try {
            setDateTime(dateFormat.parse(date));
        } catch (ParseException e) {
            dateChanged = false;
        }
        return dateChanged;
    }

    public void setDateTime(Date date) {
        dateTime = date.getTime();
    }

    public Date toDate() {
        return new Date(dateTime);
    }

    public String toISO8601() {
        if (getMilliseconds() == 0)
            return toString(ISO_8601_UTC_PATTERN);
        return toString(ISO_8601_UTC_MILLIS_PATTERN);
    }

    public String toRFC1123() {
        return toString(RFC_1123_PATTERN);
    }

    /**
     * Returns on a RFC 1123 format.
     */
    public String toString() {
        return toRFC1123();
    }

    protected String toString(String pattern) {
        dateFormat.applyPattern(pattern);
        return dateFormat.format(toDate());
    }
}


package org.kie.eclipse.utils;

import java.io.File;
import java.net.URISyntaxException;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;
import org.kie.eclipse.IKieConstants;
import org.kie.eclipse.server.IKieRepositoryHandler;
import org.kie.eclipse.server.IKieServerHandler;
import org.kie.eclipse.server.IKieServiceDelegate;

public class PreferencesUtils implements IKieConstants {

	public PreferencesUtils() {
	}

    public static String getRepoRoot(final IKieRepositoryHandler repository) {
        final IKieServerHandler server = (IKieServerHandler) repository.getRoot();

        final boolean useDefaultGitPath = server.getPreference(IKieConstants.PREF_USE_DEFAULT_GIT_PATH, false);
        final String defaultRepoRoot = getDefaultRepositoryDir();

        if (useDefaultGitPath) {
            return defaultRepoRoot;
        }

        final String repoRoot = defaultRepoRoot + File.separator + server.getPreferenceName(null).replace(IKieConstants.PREF_PATH_SEPARATOR.charAt(0), File.separator.charAt(0));
        return server.getPreference(IKieConstants.PREF_GIT_REPO_PATH, repoRoot);
    }

    public static String getRepoPath(final IKieRepositoryHandler repository) {
        return getRepoRoot(repository) + File.separator + repository.getName();
    }

    public static URIish getRepoURI(final IKieRepositoryHandler repository) {
        final IKieServiceDelegate delegate = repository.getDelegate();

        final String host = delegate.getServer().getHost();
        final int port = delegate.getGitPort();
        final String username = delegate.getUsername();
        final String potentialUsername = username == null || username.isEmpty() ? "" : username + "@";
        final String repoPath = repository.getParent().getName() + File.separator + repository.getName();

        try {
            // URI is in the form: ssh://admin@localhost:8001/spaceName/projectName
            return new URIish("ssh://" + potentialUsername + host + ":" + port + "/" + repoPath);
        } catch (final URISyntaxException e) {
            e.printStackTrace();
            return null;
        }
    }

    //
    //
	// FIXME: As soon as I find out how to get the default git repository directory root
	// from EGit, this needs to go away - there's a bunch of code here that was copied
	// directly from the EGit RepositoryUtil class
	private static final String core_defaultRepositoryDir = "core_defaultRepositoryDir"; //$NON-NLS-1$
	private static final String deprecated_defaultRespositoryDir = "default_repository_dir"; //$NON-NLS-1$
	private static final String egitPluginId = "org.eclipse.egit.core"; //$NON-NLS-1$
	private static final String deprecatedEgitPreferences = "org.eclipse.egit.ui"; //$NON-NLS-1$

	public static String getDefaultRepositoryDir() {
		String key = core_defaultRepositoryDir;
		String dir = getDeprecatedRepoRootPreference();
		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(egitPluginId);
		if (dir == null) {
			dir = p.get(key, getDefaultDefaultRepositoryDir());
		}

		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
		String result;
		try {
			result = manager.performStringSubstitution(dir);
		} catch (CoreException e) {
			result = ""; //$NON-NLS-1$
		}
		if (result == null || result.isEmpty()) {
			result = ResourcesPlugin.getWorkspace().getRoot().getRawLocation().toOSString();
		}
		return result;
	}

	private static String getDefaultDefaultRepositoryDir() {
		return new File(FS.DETECTED.userHome(), "git").getPath(); //$NON-NLS-1$
	}

	private static String getDeprecatedRepoRootPreference() {
		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(deprecatedEgitPreferences);
		String value = p.get(deprecated_defaultRespositoryDir, null);
		if (value != null && value.isEmpty()) {
			value = null;
		}
		return value;
	}
}


/*
 * Copyright 2015 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 *      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.kie.eclipse;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator extends AbstractUIPlugin implements BundleActivator {

	// The plug-in ID
	public static final String PLUGIN_ID = "org.kie.eclipse"; //$NON-NLS-1$

	private static BundleContext context;
	private static Activator instance;
	private static boolean debug = false;

	public static BundleContext getContext() {
		return context;
	}

	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext bundleContext) throws Exception {
		context = bundleContext;
		instance = this;
	}

	public static Activator getDefault() {
		return instance;
	}

	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext bundleContext) throws Exception {
		context = null;
		instance = null;
		super.stop(bundleContext);
	}

    public static ImageDescriptor getImageDescriptor(String path) {
        ImageRegistry registry = instance.getImageRegistry();
        ImageDescriptor descriptor = registry.getDescriptor( path );
        if ( descriptor == null ) {
            descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID,path);
            registry.put(path,descriptor);
        }
        return descriptor;
    }

	public static Image getImage(String id) {
		getImageDescriptor(id);
		return instance.getImageRegistry().get(id);
	}

	public static void println(Object arg) {
		if (debug)
			System.out.println(arg);
	}

	public static void print(Object arg) {
		if (debug)
			System.out.print(arg);
	}

	/**
	 * Utility to create an error status for this plug-in.
	 *
	 * @param message User comprehensible message
	 * @param thr cause
	 * @return an initialized error status
	 */
	public static IStatus error(final String message, final Throwable thr) {
		return new Status(IStatus.ERROR, PLUGIN_ID, 0,	message, thr);
	}

	/**
	 * Utility method to log errors in the Egit plugin.
	 * @param message User comprehensible message
	 * @param thr The exception through which we noticed the error
	 */
	public static void logError(final String message, final Throwable thr) {
		getDefault().getLog().log(error(message, thr));
	}
}


package org.kie.eclipse.navigator.preferences;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IWorkbenchPropertyPage;
import org.eclipse.ui.dialogs.PropertyPage;

public abstract class FieldEditorPropertyPage extends PropertyPage implements IWorkbenchPropertyPage, IPropertyChangeListener {
	/**
	 * Layout constant (value 0) indicating that each field editor
	 * is handled as a single component.
	 */
	public static final int FLAT = 0;

	/**
	 * Layout constant (value 1) indicating that the field editors'
	 * basic controls are put into a grid layout.
	 */
	public static final int GRID = 1;

	/**
	 * The vertical spacing used by layout styles FLAT and
	 * GRID.
	 */
	protected static final int VERTICAL_SPACING = 10;

	/**
	 * The margin width used by layout styles FLAT and
	 * GRID.
	 */
	protected static final int MARGIN_WIDTH = 0;

	/**
	 * The margin height used by layout styles FLAT and
	 * GRID.
	 */
	protected static final int MARGIN_HEIGHT = 0;

	/**
	 * The field editors, or null if not created yet.
	 */
	private List<FieldEditor> fields = null;

	/**
	 * The layout style; either FLAT or GRID.
	 */
	private int style;

	/**
	 * The first invalid field editor, or null if all field editors
	 * are valid.
	 */
	private FieldEditor invalidFieldEditor = null;

	/**
	 * The parent composite for field editors
	 */
	private Composite fieldEditorParent;

	public FieldEditorPropertyPage() {
	}

	public FieldEditorPropertyPage(int style) {
		this();
		this.style = style;
	}

	/**
	 * Adds the given field editor to this page.
	 *
	 * @param editor the field editor
	 */
	protected void addField(FieldEditor editor) {
		if (fields == null) {
			fields = new ArrayList<FieldEditor>();
		}
		// Set the actual preference name based on the current selection
		// in the Kie Navigator tree view. The preference name is constructed
		// from the path to the selected tree node by getPreferenceName().
		String name = editor.getPreferenceName();
		editor.setPreferenceName(getPreferenceName(name));
		fields.add(editor);
	}

	protected abstract String getPreferenceName(String name);

	/**
	 * Adjust the layout of the field editors so that they are properly aligned.
	 */
	protected void adjustGridLayout() {
		int numColumns = calcNumberOfColumns();
		((GridLayout) fieldEditorParent.getLayout()).numColumns = numColumns;
		if (fields != null) {
			for (int i = 0; i < fields.size(); i++) {
				FieldEditor fieldEditor = fields.get(i);
				fieldEditor.fillIntoGrid(fieldEditorParent, numColumns);
			}
		}
	}

	/**
	 * Applys the font to the field editors managed by this page.
	 */
	protected void applyFont() {
		if (fields != null) {
			Iterator<FieldEditor> e = fields.iterator();
			while (e.hasNext()) {
				FieldEditor pe = e.next();
				// pe.applyFont();
			}
		}
	}

	/**
	 * Calculates the number of columns needed to host all field editors.
	 *
	 * @return the number of columns
	 */
	private int calcNumberOfColumns() {
		int result = 0;
		if (fields != null) {
			Iterator<FieldEditor> e = fields.iterator();
			while (e.hasNext()) {
				FieldEditor pe = e.next();
				result = Math.max(result, pe.getNumberOfControls());
			}
		}
		return result;
	}

	/**
	 * Recomputes the page's error state by calling isValid for
	 * every field editor.
	 */
	protected void checkState() {
		boolean valid = true;
		invalidFieldEditor = null;
		// The state can only be set to true if all
		// field editors contain a valid value. So we must check them all
		if (fields != null) {
			int size = fields.size();
			for (int i = 0; i < size; i++) {
				FieldEditor editor = fields.get(i);
				valid = valid && editor.isValid();
				if (!valid) {
					invalidFieldEditor = editor;
					break;
				}
			}
		}
		setValid(valid);
	}

	@Override
	public IPreferenceStore getPreferenceStore() {
		return org.kie.eclipse.Activator.getDefault().getPreferenceStore();
	}

	/*
	 * (non-Javadoc) Method declared on PreferencePage.
	 */
	@Override
	protected Control createContents(Composite parent) {
		fieldEditorParent = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		fieldEditorParent.setLayout(layout);
		fieldEditorParent.setFont(parent.getFont());

		createFieldEditors();

		if (style == GRID) {
			adjustGridLayout();
		}

		initialize();
		checkState();
		return fieldEditorParent;
	}

	/**
	 * Creates the page's field editors.
	 *

	 * The default implementation of this framework method does nothing.
	 * Subclass must implement this method to create the field editors.
	 *

	 *

	 * Subclasses should call getFieldEditorParent to obtain the
	 * parent control for each field editor. This same parent should not be used
	 * for more than one editor as the parent may change for each field editor
	 * depending on the layout style of the page
	 *

	 */
	protected abstract void createFieldEditors();

	/**
	 * Gets the initial property page ID based on the current selection.
	 *
	 * @return the page ID string
	 */
	protected abstract String getInitialPageId();

	/**
	 * The field editor preference page implementation of an
	 * IDialogPage method disposes of this page's controls and
	 * images. Subclasses may override to release their own allocated SWT
	 * resources, but must call super.dispose.
	 */
	@Override
	public void dispose() {
		super.dispose();
		if (fields != null) {
			Iterator<FieldEditor> e = fields.iterator();
			while (e.hasNext()) {
				FieldEditor pe = e.next();
				pe.setPage(null);
				pe.setPropertyChangeListener(null);
				pe.setPreferenceStore(null);
			}
		}
	}

	/**
	 * Returns a parent composite for a field editor.
	 *

	 * This value must not be cached since a new parent may be created each time
	 * this method called. Thus this method must be called each time a field
	 * editor is constructed.
	 *

	 *
	 * @return a parent
	 */
	protected Composite getFieldEditorParent() {
		if (style == FLAT) {
			// Create a new parent for each field editor
			Composite parent = new Composite(fieldEditorParent, SWT.NULL);
			parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			return parent;
		}
		// Just return the parent
		return fieldEditorParent;
	}

	/**
	 * Initializes all field editors.
	 */
	protected void initialize() {
		if (fields != null) {
			Iterator<FieldEditor> e = fields.iterator();
			while (e.hasNext()) {
				FieldEditor pe = e.next();
				pe.setPage(this);
				pe.setPropertyChangeListener(this);
				pe.setPreferenceStore(getPreferenceStore());
				pe.load();
			}
		}
	}

	/**
	 * The field editor preference page implementation of a
	 * PreferencePage method loads all the field editors with their
	 * default values.
	 */
	@Override
	protected void performDefaults() {
		if (fields != null) {
			Iterator<FieldEditor> e = fields.iterator();
			while (e.hasNext()) {
				FieldEditor pe = e.next();
				pe.loadDefault();
			}
		}
		// Force a recalculation of my error state.
		checkState();
		super.performDefaults();
	}

	/**
	 * The field editor preference page implementation of this
	 * PreferencePage method saves all field editors by calling
	 * FieldEditor.store. Note that this method does not save the
	 * preference store itself; it just stores the values back into the
	 * preference store.
	 *
	 * @see FieldEditor#store()
	 */
	@Override
	public boolean performOk() {
		if (fields != null) {
			Iterator<FieldEditor> e = fields.iterator();
			while (e.hasNext()) {
				FieldEditor pe = e.next();
				pe.store();
				// pe.setPresentsDefaultValue(false);
			}
		}
		return true;
	}

	/**
	 * The field editor preference page implementation of this
	 * IPreferencePage (and IPropertyChangeListener)
	 * method intercepts IS_VALID events but passes other events on
	 * to its superclass.
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {

		if (event.getProperty().equals(FieldEditor.IS_VALID)) {
			boolean newValue = ((Boolean) event.getNewValue()).booleanValue();
			// If the new value is true then we must check all field editors.
			// If it is false, then the page is invalid in any case.
			if (newValue) {
				checkState();
			}
			else {
				invalidFieldEditor = (FieldEditor) event.getSource();
				setValid(newValue);
			}
		}
	}

	/*
	 * (non-Javadoc) Method declared on IDialog.
	 */
	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible && invalidFieldEditor != null) {
			invalidFieldEditor.setFocus();
		}
	}

}