/*
 * 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 org.eclipse.webdav.internal.kernel.Policy;

/**
 * Assert is useful for for embedding runtime sanity checks
 * in code.
 * The predicate methods all test a condition and throw some
 * type of unchecked exception if the condition does not hold.
 *

 * Assertion failure exceptions, like most runtime exceptions, are
 * thrown when something is misbehaving. Assertion failures are invariably
 * unspecified behavior; consequently, clients should never rely on
 * these being thrown (and certainly should not being catching them
 * specifically).
 */
public class Assert {
    /** Block instantiation. */
    private Assert() {
        super();
    }

    /** Asserts that an argument is legal. If the given boolean is
     * not true, an IllegalArgumentException
     * is thrown.
     *
     * @exception IllegalArgumentException Thrown if the legality test failed
     */
    static public boolean isLegal(boolean expression) {
        return isLegal(expression, ""); //$NON-NLS-1$
    }

    /** Asserts that an argument is legal. If the given boolean is
     * not true, an IllegalArgumentException
     * is thrown.
     * The given message is included in that exception, to aid debugging.
     *
     * @exception IllegalArgumentException Thrown if the legality test failed
     */
    static public boolean isLegal(boolean expression, String message) {
        if (!expression)
            throw new IllegalArgumentException(message);
        return expression;
    }

    /** Asserts that the given object is not null. If this
     * is not the case, some kind of unchecked exception is thrown.
     */
    static public void isNotNull(Object o) {
        isNotNull(o, ""); //$NON-NLS-1$
    }

    /** Asserts that the given object is not null. If this
     * is not the case, some kind of unchecked exception is thrown.
     * The given message is included in that exception, to aid debugging.
     */
    static public void isNotNull(Object o, String message) {
        if (o == null)
            throw new AssertionFailedException(Policy.bind("assert.null", message)); //$NON-NLS-1$
    }

    /** Asserts that the given boolean is true. If this
     * is not the case, some kind of unchecked exception is thrown.
     */
    static public boolean isTrue(boolean expression) {
        return isTrue(expression, ""); //$NON-NLS-1$
    }

    /** Asserts that the given boolean is true. If this
     * is not the case, some kind of unchecked exception is thrown.
     * The given message is included in that exception, to aid debugging.
     */
    static public boolean isTrue(boolean expression, String message) {
        if (!expression)
            throw new AssertionFailedException(Policy.bind("assert.fail", message)); //$NON-NLS-1$
        return expression;
    }
}


/*
 * 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 org.eclipse.webdav.Policy;
import org.w3c.dom.Element;

/**
 * An element editor for the WebDAV propstat element. See RFC2518
 * section 12.9.1.1 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 org.eclipse.webdav.http.client.Response
 * @see Prop
 */
public class PropStat extends ElementEditor {
    /**
     * An ordered collection of the element names of the propstat
     * element's children.
     */
    protected static final String[] childNames = new String[] {"prop", "status", "responsedescription"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

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

    /**
     * Returns this propstat's prop.
     *
     * @return this propstat's prop
     * @throws MalformedElementException if there is reason to believe that
     *         this editor's underlying element is not well formed
     */
    public Prop getProp() throws MalformedElementException {
        Element prop = getFirstChild(root, "prop"); //$NON-NLS-1$
        ensureNotNull(Policy.bind("ensure.missingPropElmt"), prop); //$NON-NLS-1$
        return new Prop(prop);
    }

    /**
     * Returns this propstat's response description.
     *
     * @return this propstat's response description
     * @throws MalformedElementException if there is reason to believe that
     *         this editor's underlying element is not well formed
     */
    public String getResponseDescription() throws MalformedElementException {
        return getChildText(root, "responsedescription", false); //$NON-NLS-1$
    }

    /**
     * Returns this propstat's status.
     *
     * @return this propstat's status
     * @throws MalformedElementException if there is reason to believe that
     *         this editor's underlying element is not well formed
     */
    public String getStatus() throws MalformedElementException {
        String status = getChildText(root, "status", false); //$NON-NLS-1$
        ensureNotNull(Policy.bind("ensure.missingStatusElmt"), status); //$NON-NLS-1$
        return status;
    }

    /**
     * Returns this propstat's status code.
     *
     * @return this propstat's status code
     * @throws MalformedElementException if there is reason to believe that
     *         this editor's underlying element is not well formed
     */
    public int getStatusCode() throws MalformedElementException {
        return new Status(getStatus()).getStatusCode();
    }

    /**
     * Creates and sets a new prop on this propstat and returns an editor on
     * it.
     *
     * @return an editor on a new prop element
     */
    public Prop setProp() {
        Element prop = setChild(root, "prop", childNames, true); //$NON-NLS-1$
        try {
            return new Prop(prop);
        } catch (MalformedElementException e) {
            Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
            return null; // Never reached.
        }
    }

    /**
     * Sets this propstat's response description to the given value. If the
     * value is null and a response description has already
     * been set, it is removed.
     *
     * @param value a response description, or null
     */
    public void setResponseDescription(String value) {
        if (value == null) {
            Element child = getLastChild(root, "responsedescription"); //$NON-NLS-1$
            if (child != null)
                root.removeChild(child);
        } else
            setChild(root, "responsedescription", value, childNames, false); //$NON-NLS-1$
    }

    /**
     * Sets the status on this propstat to the given status. The status
     * must not be null.
     *
     * @param status the status for this propstat
     */
    public void setStatus(String status) {
        Assert.isNotNull(status);
        setChild(root, "status", status, childNames, true); //$NON-NLS-1$
    }
}


/*
 * 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.completion;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import org.drools.compiler.lang.Location;
import org.drools.eclipse.DroolsEclipsePlugin;
import org.drools.eclipse.DroolsPluginImages;
import org.drools.eclipse.dsl.editor.DSLAdapter;
import org.drools.eclipse.dsl.editor.DSLRuleEditor;
import org.drools.eclipse.editors.AbstractRuleEditor;
import org.drools.eclipse.editors.completion.RuleCompletionProcessor;
import org.drools.eclipse.editors.completion.RuleCompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.swt.graphics.Image;

/**
 * For handling DSL rules.
 */
public class DSLRuleCompletionProcessor extends RuleCompletionProcessor {

    private static final Image DSL_ICON =
        DroolsPluginImages.getImage(DroolsPluginImages.DSL_EXPRESSION);

    public DSLRuleCompletionProcessor(AbstractRuleEditor editor) {
        super(editor);
    }

    protected DSLRuleEditor getDSLRuleEditor() {
        return (DSLRuleEditor) getEditor();
    }

    protected void addRHSCompletionProposals(List<ICompletionProposal> list, int documentOffset, String prefix, String backText,
            String conditions, String consequence) {
        // super.addRHSCompletionProposals(list, documentOffset, prefix, backText, conditions, consequence);
        DSLAdapter adapter = getDSLRuleEditor().getDSLAdapter();
        if (adapter != null) {
            List<String> dslConsequences = adapter.getDSLTree().getConsequenceChildrenList(prefix, true);
            addDSLProposals(list, documentOffset, prefix, dslConsequences);
        }
    }

    protected void addLHSCompletionProposals(List<ICompletionProposal> list, int documentOffset,
            Location location, String prefix, String backText) {
        // super.addLHSCompletionProposals(list, documentOffset, location, prefix, backText);
        DSLAdapter adapter = getDSLRuleEditor().getDSLAdapter();
        if (adapter != null) {
            String lastobj = this.getLastNonDashLine(backText);
            String last = this.getLastLine(backText);
            // we have to check if the last line is when. if it is we set
            // the last line to zero length string
            boolean firstLine = false;
            if (lastobj.equals("when")) {
                firstLine = true;
                last = "";
                lastobj = "*";
            }
            last = last.trim();
            // pass the last string in the backText to getProposals
            List<String> dslConditions = this.getProposals(adapter, lastobj, last, firstLine);
            // if we couldn't find any matches, we add the list from
            // the DSLAdapter so that there's something
//            if (dslConditions.size() == 0) {
//                dslConditions.addAll(adapter.listConditionItems());
//            }
            addDSLProposals(list, documentOffset, last, dslConditions);
        }
    }

    private void addDSLProposals(final List<ICompletionProposal> list, int documentOffset, final String prefix, List<String> dslItems) {
        for (String consequence : dslItems) {
            RuleCompletionProposal p = new RuleCompletionProposal(
                documentOffset - prefix.length(), prefix.length(), consequence);
            p.setImage(DSL_ICON);
            list.add(p);
        }
    }

    /**
     * because of how the backText works, we need to get the last line, so that
     * we can pass it to the DSLUtility
     *
     * @param backText
     * @return
     */
    public String getLastLine(String backText) {
        BufferedReader breader = new BufferedReader(new StringReader(backText));
        String last = "";
        String line = null;
        try {
            while ((line = breader.readLine()) != null) {
                // only if the line has text do we set last to it
                if (line.length() > 0) {
                    last = line;
                }
            }
        } catch (IOException e) {
            DroolsEclipsePlugin.log(e);
        }
        // now that all the conditions for a single object are on the same line
        // we need to check for the left parenthesis
        if (last.indexOf("(") > -1) {
            last = last.substring(last.lastIndexOf("(") + 1);
        }
        // if the string has a comma "," we get the substring starting from
        // the index after the last comma
        if (last.indexOf(",") > -1) {
            last = last.substring(last.lastIndexOf(",") + 1);
        }
        // if the line ends with right parenthesis, we change it to zero length
        // string
        if (last.endsWith(")")) {
            last = "";
        }
        return last;
    }

    /**
     * Returns the last line that doesn't start with a dash
     *
     * @param backText
     * @return
     */
    public String getLastNonDashLine(String backText) {
        BufferedReader breader = new BufferedReader(new StringReader(backText));
        String last = "";
        String line = null;
        try {
            while ((line = breader.readLine()) != null) {
                // there may be blank lines, so we trim first
                line = line.trim();
                // only if the line has text do we set last to it
                if (line.length() > 0 && !line.startsWith("-")) {
                    last = line;
                }
            }
        } catch (IOException e) {
            DroolsEclipsePlugin.log(e);
        }
        if (last.indexOf("(") > -1 && !last.endsWith(")")) {
            last = last.substring(0, last.indexOf("("));
        } else if (last.indexOf("(") > -1 && last.endsWith(")")) {
            last = "";
        }
        return last;
    }

    /**
     * The DSLTree is configurable. It can either return just the child of the
     * last token found, or it can traverse the tree and generate all the
     * combinations beneath the last matching node. TODO I don't know how to add
     * configuration to the editor, so it needs to be hooked up to the
     * configuration for the editor later.
     *
     * @param last
     * @return
     */
    protected List<String> getProposals(DSLAdapter adapter, String obj, String last, boolean firstLine) {
        if (last.length() == 0) {
            last = " ";
        }
        return adapter.getDSLTree().getChildrenList(obj, last, true, firstLine);
    }
}


/*
 * 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;

import java.text.MessageFormat;
import java.util.*;

public class Policy {
    private static String bundleName = "org.eclipse.webdav.messages";//$NON-NLS-1$
    private static ResourceBundle bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());

    /**
     * Lookup the message with the given ID in this catalog
     */
    public static String bind(String id) {
        return bind(id, (String[]) null);
    }

    /**
     * Lookup the message with the given ID in this catalog and bind its
     * substitution locations with the given string.
     */
    public static String bind(String id, String binding) {
        return bind(id, new String[] {binding});
    }

    /**
     * Lookup the message with the given ID in this catalog and bind its
     * substitution locations with the given strings.
     */
    public static String bind(String id, String binding1, String binding2) {
        return bind(id, new String[] {binding1, binding2});
    }

    /**
     * Lookup the message with the given ID in this catalog and bind its
     * substitution locations with the given string values.
     */
    public static String bind(String id, String[] bindings) {
        if (id == null)
            return "No message available";//$NON-NLS-1$
        String message = null;
        try {
            message = bundle.getString(id);
        } catch (MissingResourceException e) {
            // If we got an exception looking for the message, fail gracefully by just returning
            // the id we were looking for.  In most cases this is semi-informative so is not too bad.
            return "Missing message: " + id + "in: " + bundleName;//$NON-NLS-1$ //$NON-NLS-2$
        }
        if (bindings == null)
            return message;
        return MessageFormat.format(message, bindings);
    }
}


/*
 * 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.utils;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;
import org.eclipse.webdav.Policy;
import org.eclipse.webdav.internal.kernel.utils.Assert;

/**
 * Encodes a URL into an ASCII readable
 * URL that is safe for transport. Encoded
 * URLs can be decoded using the URLDecoder.
 *
 * @see URLDecoder
 */
public final class URLEncoder {
    /**
     * Prevents instances from being created.
     */
    private URLEncoder() {
        super();
    }

    /**
     * Encodes the given URL into an ASCII
     * readable URL that is safe for transport. Returns the
     * result.
     *
     * @return the result of encoding the given URL into an
     *         ASCII readable URL that is safe for
     *         transport
     */
    public static String encode(String url) {
        try {
            return encode(new URL(url)).toString();
        } catch (MalformedURLException e) {
            // ignore or log?
        }

        String file;
        String ref = null;

        int lastSlashIndex = url.lastIndexOf('/');
        int lastHashIndex = url.lastIndexOf('#');
        if ((lastHashIndex - lastSlashIndex > 1) && lastHashIndex < url.length() - 1) {
            file = url.substring(0, lastHashIndex);
            ref = url.substring(lastHashIndex + 1, url.length());
        } else {
            file = url;
        }

        return encode(file, ref);
    }

    /**
     * Encodes the given file and reference parts of a URL into
     * an ASCII readable String that is safe for
     * transport. Returns the result.
     *
     * @return the result of encoding the given file and reference parts of
     *         a URL into an ASCII readable
     *         String that is safe for transport
     */
    public static String encode(String file, String ref) {
        StringBuffer buf = new StringBuffer();
        StringTokenizer tokenizer = new StringTokenizer(file, "/", true); //$NON-NLS-1$

        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (token.equals("/")) { //$NON-NLS-1$
                buf.append(token);
            } else {
                buf.append(encodeSegment(token));
            }
        }

        if (ref != null) {
            buf.append('#');
            buf.append(encodeSegment(ref));
        }

        return buf.toString();
    }

    /**
     * Encodes the given URL into an ASCII
     * readable URL that is safe for transport. Returns the
     * result.
     *
     * @return the result of encoding the given URL into an
     *         ASCII readable URL that is safe for
     *         transport
     */
    public static URL encode(URL url) {
        String file = url.getFile();
        String ref = url.getRef();

        try {
            return new URL(url.getProtocol(), url.getHost(), url.getPort(), encode(file, ref));
        } catch (MalformedURLException e) {
            Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
        }

        return null;
    }

    private static String encodeSegment(String segment) {
        StringBuffer result = new StringBuffer(segment.length());

        for (int i = 0; i < segment.length(); ++i) {
            char c = segment.charAt(i);
            if (mustEncode(c)) {
                byte[] bytes = null;
                try {
                    bytes = new Character(c).toString().getBytes("UTF8"); //$NON-NLS-1$
                } catch (UnsupportedEncodingException e) {
                    Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
                }
                for (int j = 0; j < bytes.length; ++j) {
                    result.append('%');
                    result.append(Integer.toHexString((bytes[j] >> 4) & 0x0F));
                    result.append(Integer.toHexString(bytes[j] & 0x0F));
                }
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    private static boolean mustEncode(char c) {
        if (c >= 'a' && c <= 'z')
            return false;
        if (c >= 'A' && c <= 'Z')
            return false;
        if (c >= '0' && c <= '9')
            return false;
        if (c >= '\'' && c <= '.')
            return false;
        if (c == '!' || c == '$' || c == '_')
            return false;
        return true;
    }
}


/*
 * 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.part;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.drools.eclipse.editors.rete.figure.ConnectionFigure;
import org.drools.eclipse.editors.rete.model.ModelElement;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PolylineDecoration;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;

/**
 * Edit part for Connection model elements.
 */
class ConnectionEditPart extends AbstractConnectionEditPart
    implements
    PropertyChangeListener {

    /* (non-Javadoc)
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#activate()
     */
    public void activate() {
        if ( !isActive() ) {
            super.activate();
            ((ModelElement) getModel()).addPropertyChangeListener( this );
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
     */
    protected void createEditPolicies() {
        installEditPolicy( EditPolicy.CONNECTION_ENDPOINTS_ROLE,
                           new ConnectionEndpointEditPolicy() );
    }

    /* (non-Javadoc)
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
     */
    protected IFigure createFigure() {
        PolylineConnection connection = new ConnectionFigure();
        PolylineDecoration decoration = new PolylineDecoration();
        connection.setTargetDecoration( decoration );
        return connection;
    }

    /* (non-Javadoc)
     * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#deactivate()
     */
    public void deactivate() {
        if ( isActive() ) {
            super.deactivate();
            ((ModelElement) getModel()).removePropertyChangeListener( this );
        }
    }

    /* (non-Javadoc)
     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
     */
    public void propertyChange(PropertyChangeEvent evt) {
        // Doing nothing
    }

}


/*
 * 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.jbpm.eclipse.wizard.project;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.jbpm.eclipse.JBPMEclipsePlugin;
import org.jbpm.eclipse.preferences.JBPMProjectPreferencePage;
import org.jbpm.eclipse.util.JBPMRuntime;
import org.jbpm.eclipse.util.JBPMRuntimeManager;
import org.kie.eclipse.runtime.IRuntime;
import org.kie.eclipse.runtime.IRuntimeManager;
import org.kie.eclipse.utils.FileUtils;
import org.kie.eclipse.wizard.project.AbstractKieEmptyProjectWizardPage;
import org.kie.eclipse.wizard.project.AbstractKieOnlineExampleProjectWizardPage;
import org.kie.eclipse.wizard.project.AbstractKieProjectStartWizardPage;
import org.kie.eclipse.wizard.project.AbstractKieProjectWizard;
import org.kie.eclipse.wizard.project.IKieProjectWizardPage;
import org.kie.eclipse.wizard.project.IKieSampleFilesProjectWizardPage;
import org.kie.eclipse.runtime.AbstractRuntime.Version;

/**
 * A wizard to create a new jBPM project.
 *
 */
public class NewJBPMProjectWizard extends AbstractKieProjectWizard {

    private EmptyJBPMProjectWizardPage emptyProjectPage;
    private SampleJBPMProjectWizardPage sampleFilesProjectPage;

    @Override
	protected void initializeDefaultPageImageDescriptor() {
        ImageDescriptor desc = JBPMEclipsePlugin.getImageDescriptor("icons/jbpm-large.png");
        setDefaultPageImageDescriptor(desc);
    }

    @Override
	protected void createOutputLocation(IJavaProject project, IProgressMonitor monitor)
            throws JavaModelException, CoreException {
    	String target = "bin";
    	if (startPage.getInitialProjectContent()==IKieProjectWizardPage.EMPTY_PROJECT)
    		target = emptyProjectPage.shouldCreateMavenProject() ? "target/classes" : "bin";
    	else if (startPage.getInitialProjectContent()==IKieProjectWizardPage.SAMPLE_FILES_PROJECT)
    		target = sampleFilesProjectPage.shouldCreateMavenProject() ? "target/classes" : "bin";

        IFolder folder = project.getProject().getFolder(target);
        FileUtils.createFolder(folder, monitor);
        IPath path = folder.getFullPath();
        project.setOutputLocation(path, null);
    }

    @Override
	protected void setClasspath(IJavaProject project, IProgressMonitor monitor)
            throws JavaModelException, CoreException {
        super.setClasspath(project, monitor);
    	if (startPage.getInitialProjectContent()==IKieProjectWizardPage.EMPTY_PROJECT) {
    		if (!emptyProjectPage.shouldCreateMavenProject())
	        	FileUtils.addJUnitLibrary(project, monitor);
    	}
    	else if (startPage.getInitialProjectContent() == IKieProjectWizardPage.SAMPLE_FILES_PROJECT) {
	        if (!sampleFilesProjectPage.shouldCreateMavenProject() && sampleFilesProjectPage.shouldCreateJUnitFile())
	        	FileUtils.addJUnitLibrary(project, monitor);
        }
    }

    protected void addSourceFolders(IJavaProject project, IProgressMonitor monitor) throws JavaModelException, CoreException {
    	if (startPage.getInitialProjectContent()!=IKieProjectWizardPage.ONLINE_EXAMPLE_PROJECT) {
	        List<IClasspathEntry> list = new ArrayList<IClasspathEntry>();
	        list.addAll(Arrays.asList(project.getRawClasspath()));
	        addSourceFolder(project, list, "src/main/java", monitor);
        	addSourceFolder(project, list, "src/main/resources", monitor);
	        project.setRawClasspath((IClasspathEntry[]) list.toArray(new IClasspathEntry[list.size()]), null);
    	}
    }

    @Override
	protected void createInitialContent(IJavaProject javaProject, IProgressMonitor monitor)
            throws CoreException, JavaModelException, IOException {
    	if (startPage.getInitialProjectContent()==IKieProjectWizardPage.EMPTY_PROJECT) {
    		createDefaultPackages(javaProject, monitor);
    	}
    	else if (startPage.getInitialProjectContent() == IKieProjectWizardPage.SAMPLE_FILES_PROJECT) {
    		String exampleType = sampleFilesProjectPage.getSampleType();
    		createProcess(javaProject, monitor, exampleType);
	    	if (sampleFilesProjectPage.shouldCreateJUnitFile()) {
	    		createProcessSampleJUnit(javaProject, exampleType, monitor);
	    	}
    	}
	    super.createInitialContent(javaProject, monitor);
	    createLoggerFile(javaProject, monitor);
	}

    private void createDefaultPackages(IJavaProject project, IProgressMonitor monitor) throws CoreException {
		IFolder folder = project.getProject().getFolder("src/main/java/com/sample");
		FileUtils.createFolder(folder, monitor);
		folder = project.getProject().getFolder("src/main/resources/com/sample");
		FileUtils.createFolder(folder, monitor);
    }

    private void createLoggerFile(IJavaProject project, IProgressMonitor monitor) throws CoreException {
	    String fileName = "org/jbpm/eclipse/wizard/project/logback-test.xml.template";
        IFolder folder = project.getProject().getFolder("src/main/resources");
        FileUtils.createFolder(folder, monitor);
        IFile file = folder.getFile("logback-test.xml");
        InputStream inputstream = getClass().getClassLoader().getResourceAsStream(fileName);
        if (!file.exists()) {
            file.create(inputstream, true, monitor);
        } else {
            file.setContents(inputstream, true, false, monitor);
        }
	}

    /**
     * Create the sample process file.
     * @throws IOException
     */
	private void createProcess(IJavaProject project, IProgressMonitor monitor, String exampleType)
			throws CoreException, IOException {
		// create the process (sample.bpmn) file
		String fileName = "org/jbpm/eclipse/wizard/project/" + exampleType + ".bpmn.template";
		IFolder folder = null;
		folder = project.getProject().getFolder("src/main/resources/com/sample");
		FileUtils.createFolder(folder, monitor);
		IFile file = folder.getFile("sample.bpmn");
		InputStream inputstream = getClass().getClassLoader().getResourceAsStream(fileName);
		if (!file.exists()) {
			file.create(inputstream, true, monitor);
		} else {
			file.setContents(inputstream, true, false, monitor);
		}

		// create a Java main class to invoke the process
		fileName = "org/jbpm/eclipse/wizard/project/ProcessMain-" + exampleType + ".java";
		IRuntime runtime = startPage.getRuntime();
		if (runtime.getVersion().getMajor() == 5) {
			fileName += ".v5.template";
		} else {
			fileName += ".template";
		}

		folder = project.getProject().getFolder("src/main/java");
		IPackageFragmentRoot packageFragmentRoot = project.getPackageFragmentRoot(folder);
		IPackageFragment packageFragment = packageFragmentRoot.createPackageFragment("com.sample", true, monitor);
		inputstream = getClass().getClassLoader().getResourceAsStream(fileName);
		packageFragment.createCompilationUnit("ProcessMain.java", new String(FileUtils.readStream(inputstream)), true,
				monitor);

		// create persistence.xml
		if (runtime.getVersion().getMajor() == 5) {
			if ("advanced".equals(exampleType)) {
	        	folder = project.getProject().getFolder("src/main/resources/META-INF");
	    		FileUtils.createFolder(folder, monitor);
	            inputstream = getClass().getClassLoader().getResourceAsStream(
	            	"org/jbpm/eclipse/wizard/project/ProcessLauncher-advanced-persistence.xml.template");
	            file = folder.getFile("persistence.xml");
	            if (!file.exists()) {
	                file.create(inputstream, true, monitor);
	            } else {
	                file.setContents(inputstream, true, false, monitor);
	            }
			}
		}
	}

    /**
     * Create the sample process junit test file.
     */
	private void createProcessSampleJUnit(IJavaProject project, String exampleType, IProgressMonitor monitor)
			throws JavaModelException, IOException {
		String s = "org/jbpm/eclipse/wizard/project/ProcessJUnit-" + exampleType + ".java";
		IRuntime runtime = startPage.getRuntime();
		if (runtime.getVersion().getMajor()==5) {
			s += ".v5.template";
		} else {
			s += ".template";
		}
		IFolder folder = project.getProject().getFolder("src/main/java");
        IPackageFragmentRoot packageFragmentRoot = project
                .getPackageFragmentRoot(folder);
        IPackageFragment packageFragment = packageFragmentRoot
                .createPackageFragment("com.sample", true, monitor);
        InputStream inputstream = getClass().getClassLoader()
                .getResourceAsStream(s);
        packageFragment.createCompilationUnit("ProcessTest.java", new String(
                FileUtils.readStream(inputstream)), true, monitor);
	}

    @Override
	protected void createKJarArtifacts(IJavaProject project, IProgressMonitor monitor) {
    	try {
		    String fileName = "org/jbpm/eclipse/wizard/project/kmodule.xml.template";
	        IFolder folder = project.getProject().getFolder("src/main/resources/META-INF");
	        FileUtils.createFolder(folder, monitor);
	        IFile file = folder.getFile("kmodule.xml");
	        InputStream inputstream = getClass().getClassLoader().getResourceAsStream(fileName);
	        if (!file.exists()) {
	            file.create(inputstream, true, monitor);
	        } else {
	            file.setContents(inputstream, true, false, monitor);
	        }

        	String projectName = project.getProject().getName();
            String groupId = "com.sample";
            String artifactId = projectName;
            String version = "1.0.0-SNAPSHOT";
			FileUtils.createProjectFile(project, monitor, FileUtils.generatePomProperties(groupId, artifactId, version), "src/main/resources/META-INF/maven", "pom.properties");
    	}
    	catch (CoreException ex) {
    		ex.printStackTrace();
    	}
    }

	@Override
	protected void createMavenArtifacts(IJavaProject project, IProgressMonitor monitor) {
		try {
        	String projectName = project.getProject().getName();
        	String runtimeVersion = startPage.getRuntime().getVersion().toString();
            String groupId = "com.sample";
            String artifactId = projectName;
            String version = "1.0.0-SNAPSHOT";
        	if (startPage.getInitialProjectContent() == IKieProjectWizardPage.SAMPLE_FILES_PROJECT) {
        		groupId = sampleFilesProjectPage.getPomGroupId();
        		artifactId = sampleFilesProjectPage.getPomArtifactId();
        		version = sampleFilesProjectPage.getPomVersion();
        	}
        	else if (startPage.getInitialProjectContent() == IKieProjectWizardPage.EMPTY_PROJECT) {
        		groupId = emptyProjectPage.getPomGroupId();
        		artifactId = emptyProjectPage.getPomArtifactId();
        		version = emptyProjectPage.getPomVersion();
        	}

			FileUtils.createProjectFile(project, monitor, FileUtils.generatePomProperties(groupId, artifactId, version), "src/main/resources/META-INF/maven", "pom.properties");
			String fileName = "org/jbpm/eclipse/wizard/project/maven-pom.xml.template";
			InputStream inputstream = getClass().getClassLoader().getResourceAsStream(fileName);
            FileUtils.createProjectFile(project, monitor,
            		FileUtils.generatePom(inputstream, runtimeVersion, groupId, artifactId, version),
            		null, "pom.xml");
		}
		catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.wizard.project.AbstractKieProjectWizard#createStartPage(java.lang.String)
	 * Create the Wizard Start Page
	 */
	@Override
	protected IKieProjectWizardPage createStartPage(String pageId) {
		return new AbstractKieProjectStartWizardPage(pageId) {
			@Override
			public String getTitle() {
				return "Create New jBPM Project";
			}
		};
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.wizard.project.AbstractKieProjectWizard#createEmptyProjectPage(java.lang.String)
	 * Create the Empty Project Wizard Page
	 */
	@Override
	protected IKieProjectWizardPage createEmptyProjectPage(String pageId) {
		emptyProjectPage = new EmptyJBPMProjectWizardPage(EMPTY_PROJECT_PAGE);
		return emptyProjectPage;
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.wizard.project.AbstractKieProjectWizard#createSampleFilesProjectPage(java.lang.String)
	 * Create the Sample Files Project Wizard Page
	 */
	@Override
	protected IKieProjectWizardPage createSampleFilesProjectPage(String pageId) {
		sampleFilesProjectPage = new SampleJBPMProjectWizardPage(SAMPLE_FILES_PROJECT_PAGE);
		return sampleFilesProjectPage;
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.wizard.project.AbstractKieProjectWizard#createOnlineExampleProjectPage(java.lang.String)
	 * Create the Online Example Project Wizard Page
	 */
	@Override
	protected IKieProjectWizardPage createOnlineExampleProjectPage(String pageId) {
		return new AbstractKieOnlineExampleProjectWizardPage(ONLINE_EXAMPLE_PROJECT_PAGE) {
			@Override
			public String getTitle() {
				return "Create jBPM Projects from Online Examples";
			}

			@Override
			public String getDescription() {
				return "Select jBPM Example Projects";
			}

			@Override
			public IRuntimeManager getRuntimeManager() {
				return JBPMRuntimeManager.getDefault();
			}

			@Override
			public String getProductId() {
				return "jbpm";
			}
		};
	}

	/**
	 * Implementation for the Empty Project Wizard Page
	 */
	class EmptyJBPMProjectWizardPage extends AbstractKieEmptyProjectWizardPage implements IKieSampleFilesProjectWizardPage {
		public EmptyJBPMProjectWizardPage(String pageName) {
			super(pageName);
			setTitle("Create New Empty jBPM Project");
			setDescription("Select the type of jBPM Project");
		}

		@Override
		protected void createControls(Composite parent) {
		}

		@Override
		public IRuntimeManager getRuntimeManager() {
			return JBPMRuntimeManager.getDefault();
		}

		@Override
		protected IRuntime createRuntime() {
			return new JBPMRuntime();
		}

		@Override
		public int showRuntimePreferenceDialog() {
			return PreferencesUtil.createPreferenceDialogOn(getShell(),
					JBPMProjectPreferencePage.PREF_ID,
					new String[] { JBPMProjectPreferencePage.PROP_ID }, new HashMap()).open();
		}

		@Override
		public String getProductName() {
			return "jBPM";
		}

		@Override
		public String getProductId() {
			return "jbpm";
		}
	}

	class SampleJBPMProjectWizardPage extends EmptyJBPMProjectWizardPage {
		private Button simpleProcessButton;
		private Button advancedProcessButton;
		private Button addSampleJUnitTestCodeButton;
		private boolean addSampleJUnit = false;
		private String sampleType = "simple";

		public SampleJBPMProjectWizardPage(String pageName) {
			super(pageName);
			setTitle("Create New jBPM Project with Sample Files");
			setDescription("Select the samples to be included");
		}

		@Override
		protected void createControls(Composite parent) {
			simpleProcessButton = createRadioButton(parent,
				"Add a simple hello world process");
			simpleProcessButton.setSelection(true);
			simpleProcessButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					if (((Button) e.widget).getSelection()) {
						sampleType = "simple";
					}
				}
			});
			advancedProcessButton = createRadioButton(parent,
				"Add a more advanced process including human tasks and persistence");
			advancedProcessButton.setSelection(false);
			advancedProcessButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					if (((Button) e.widget).getSelection()) {
						sampleType = "advanced";
					}
				}
			});

			addSampleJUnitTestCodeButton = createCheckBox(parent,
				"Also include a sample JUnit test for the process");
			addSampleJUnitTestCodeButton.setSelection(addSampleJUnit);
			addSampleJUnitTestCodeButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					addSampleJUnit = ((Button) e.widget).getSelection();
				}
			});
		}

		public String getSampleType() {
    		return sampleType;
		}

		public boolean shouldCreateJUnitFile() {
    		return addSampleJUnit;
		}
	}
}


/*******************************************************************************
 * Copyright (c) 2011, 2012, 2013, 2014 Red Hat, Inc.
 *  All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Red Hat, Inc. - initial API and implementation
 *
 ******************************************************************************/

package org.kie.eclipse.server;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.wst.server.core.IServer;
import org.kie.eclipse.Activator;
import org.kie.eclipse.IKieConstants;

/**
 *
 */
public class KieServerHandler extends KieResourceHandler implements IKieServerHandler {

    private final IServer server;
	private IKieServiceDelegate delegate;

	/**
	 *
	 */
	public KieServerHandler(IServer server) {
		super(null,server.getName());
		this.server = server;
	}

	@Override
	public Object getResource() {
		return server;
	}

	@Override
	public void dispose() {
	}

	@Override
	public IKieServiceDelegate getDelegate() {
		if (delegate==null)
			delegate = loadDelegate();
		return delegate;
	}

	protected IKieServiceDelegate loadDelegate() {
		IKieServiceDelegate result = null;
		try {
			String serverTypeId = getServerTypeId();
			IConfigurationElement[] config = Platform.getExtensionRegistry()
					.getConfigurationElementsFor(IKieConstants.KIE_SERVICE_IMPL_ID);
			for (IConfigurationElement e : config) {
				if ("containerBinding".equals(e.getName())) {
					String serverId = e.getAttribute("serverId");
					if (serverTypeId.matches(serverId)) {
						String kieVersion = e.getAttribute("runtimeId");
						String rid = server.getRuntime().getRuntimeType().getVersion();
						// TODO: figure out how to associated KIE web app version with
						// the containerBinding delegate class. The version number is
						// not available as a REST call from KIE web app...yet.
//						if ( getRuntimeId().equals(kieVersion) )
						{
							Object o = e.createExecutableExtension("class");
							if (o instanceof IKieServiceDelegate) {
								result = (IKieServiceDelegate)o;
								result.setServer(server);
								result.setHandler(this);
								return result;
							}
						}
					}
				}
			}
		} catch (Exception ex) {
			Activator.logError(ex.getMessage(), ex);
		}

		return result;
	}

	public static boolean isSupportedServer(IServer server) {
		IConfigurationElement[] config = Platform.getExtensionRegistry()
				.getConfigurationElementsFor(IKieConstants.KIE_SERVICE_IMPL_ID);
		String serverTypeId = server.getServerType().getId();
		if (serverTypeId!=null) {
			for (IConfigurationElement e : config) {
				if ("containerBinding".equals(e.getName())) {
					String serverId = e.getAttribute("serverId");
					if (serverTypeId.matches(serverId)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * Return the version number of the KIE Workbench that is installed on the
	 * given server. If the server is not running or not responsive, use a value
	 * from the Preference Store.
	 *
	 * @param server
	 * @return
	 */
	@Override
	public String getRuntimeId() {
		IPreferenceStore store = org.kie.eclipse.Activator.getDefault().getPreferenceStore();
		String value = store.getString(getKieVersionPreferenceKey());
		return value;
	}

	public void setRuntimeId(String version) {
		IPreferenceStore store = org.kie.eclipse.Activator.getDefault().getPreferenceStore();
		store.putValue(getKieVersionPreferenceKey(), version);
	}

	public String getServerTypeId() {
		return server.getServerType().getId();
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.navigator.view.server.IKieService#getSpaces()
	 */
	@Override
	public List<IKieSpaceHandler> getSpaces() throws IOException {
		return getDelegate().getSpaces(this);
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.navigator.view.server.IKieService#getRepositories(org.kie.eclipse.navigator.view.server.IKieSpaceHandler)
	 */
	@Override
	public List<IKieRepositoryHandler> getRepositories(IKieSpaceHandler space) throws IOException {
		return getDelegate().getRepositories(space);
	}

	/* (non-Javadoc)
	 * @see org.kie.eclipse.navigator.view.server.IKieService#getProjects(org.kie.eclipse.navigator.view.server.IKieRepository)
	 */
	@Override
	public List<IKieProjectHandler> getProjects(IKieRepositoryHandler repository) throws IOException {
		return getDelegate().getProjects(repository);
	}

	@Override
	public List<? extends IKieResourceHandler> getChildren() throws Exception {
		if (children==null)
			children = new ArrayList<IKieResourceHandler>();
		if (children.isEmpty()) {
			List<IKieRepositoryHandler> allRepositories = getDelegate().getRepositories(this);
			List<IKieSpaceHandler> spaces = getDelegate().getSpaces(this);
			for (IKieRepositoryHandler r1 : allRepositories) {
				boolean contained = false;
				for (IKieSpaceHandler o : spaces) {
					for (IKieRepositoryHandler r2 : o.getRepositories()) {
						if (r1.getName().equals(r2.getName())) {
							contained = true;
							break;
						}
					}
				}
				if (!contained)
					children.add(r1);
			}
			children.addAll(spaces);
		}
		return children;
	}

    public boolean isServerRunning() {
        return server.getServerState() == IServer.STATE_STARTED;
    }

    protected String getKieVersionPreferenceKey() {
        return server.getId()+"/kieVersion";
    }

	@Override
	public boolean isLoaded() {
		return isServerRunning();
	}

	@Override
	public IServer getServer() {
		return server;
	}
}


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

/**
 * Taken from commons lang
 *
 *
Operations on arrays, primitive arrays (like int[]) and
 * primitive wrapper arrays (like Integer[]).

 *
 *
This class tries to handle null input gracefully.
 * An exception will not be thrown for a null
 * array input. However, an Object array that contains a null
 * element may throw an exception. Each method documents its behaviour.

 *
 * @since 2.0
 * @version $Id$
 */

package org.drools.eclipse.util;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

public class ArrayUtils {
    // Taken from commons ArrayUtils

    public static final int INDEX_NOT_FOUND = -1;

    /**
     *
Checks if the object is in the given array.

     *
     *
The method returns false if a null array is passed in.

     *
     * @param array  the array to search through
     * @param objectToFind  the object to find
     * @return true if the array contains the object
     */
    public static boolean contains(Object[] array,
                                   Object objectToFind) {
        return indexOf( array,
                        objectToFind ) != INDEX_NOT_FOUND;
    }

    // IndexOf search
    // ----------------------------------------------------------------------

    // Object IndexOf
    //-----------------------------------------------------------------------
    /**
     *
Finds the index of the given object in the array.

     *
     *
This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

     *
     * @param array  the array to search through for the object, may be null
     * @param objectToFind  the object to find, may be null
     * @return the index of the object within the array,
     *  {@link #INDEX_NOT_FOUND} (-1) if not found or null array input
     */
    public static int indexOf(Object[] array,
                              Object objectToFind) {
        return indexOf( array,
                        objectToFind,
                        0 );
    }

    /**
     *
Finds the index of the given object in the array starting at the given index.

     *
     *
This method returns {@link #INDEX_NOT_FOUND} (-1) for a null input array.

     *
     *
A negative startIndex is treated as zero. A startIndex larger than the array
     * length will return {@link #INDEX_NOT_FOUND} (-1).

     *
     * @param array  the array to search through for the object, may be null
     * @param objectToFind  the object to find, may be null
     * @param startIndex  the index to start searching at
     * @return the index of the object within the array starting at the index,
     *  {@link #INDEX_NOT_FOUND} (-1) if not found or null array input
     */
    public static int indexOf(Object[] array,
                              Object objectToFind,
                              int startIndex) {
        if ( array == null ) {
            return INDEX_NOT_FOUND;
        }
        if ( startIndex < 0 ) {
            startIndex = 0;
        }
        if ( objectToFind == null ) {
            for ( int i = startIndex; i < array.length; i++ ) {
                if ( array[i] == null ) {
                    return i;
                }
            }
        } else {
            for ( int i = startIndex; i < array.length; i++ ) {
                if ( objectToFind.equals( array[i] ) ) {
                    return i;
                }
            }
        }
        return INDEX_NOT_FOUND;
    }

    public static int hashCode(Object[] array) {
        final int PRIME = 31;
        if ( array == null ) return 0;
        int result = 1;
        for ( int index = 0; index < array.length; index++ ) {
            result = PRIME * result + (array[index] == null ? 0 : array[index].hashCode());
        }
        return result;
    }

    public static Object[] copyOf(Object[] original,
                                  int newLength,
                                  Class newType) {
        Object[] arr = (newType == Object[].class) ? new Object[newLength] : (Object[]) Array.newInstance( newType.getComponentType(),
                                                                                newLength );
        int len = (original.length < newLength ? original.length : newLength);
        System.arraycopy( original,
                          0,
                          arr,
                          0,
                          len );
        return arr;
    }

    /**
     * @since 1.5
     */
    public static boolean deepEquals(Object[] a1,
                                     Object[] a2) {
        if ( a1 == a2 ) return true;
        if ( a1 == null || a2 == null ) return false;
        int len = a1.length;
        if ( len != a2.length ) return false;
        for ( int i = 0; i < len; i++ ) {
            Object e1 = a1[i];
            Object e2 = a2[i];
            if ( e1 == e2 ) continue;
            if ( e1 == null ) return false;
            boolean eq = (e1.getClass() != e2.getClass() || !e1.getClass().isArray()  || !e2.getClass().isArray() ) ? e1.equals( e2 ) : (e1 instanceof Object[] && e2 instanceof Object[]) ? deepEquals( (Object[]) e1,
                                                                                (Object[]) e2 ) : (e1 instanceof byte[] && e2 instanceof byte[]) ? equals( (byte[]) e1,
                                                                                (byte[]) e2 ) : (e1 instanceof short[] && e2 instanceof short[]) ? equals( (short[]) e1,
                                                                                (short[]) e2 ) : (e1 instanceof int[] && e2 instanceof int[]) ? equals( (int[]) e1,
                                                                                (int[]) e2 ) : (e1 instanceof long[] && e2 instanceof long[]) ? equals( (long[]) e1,
                                                                                (long[]) e2 ) : (e1 instanceof char[] && e2 instanceof char[]) ? equals( (char[]) e1,
                                                                                (char[]) e2 ) : (e1 instanceof boolean[] && e2 instanceof boolean[]) ? equals( (boolean[]) e1,
                                                                                (boolean[]) e2 ) : (e1 instanceof float[] && e2 instanceof float[]) ? equals( (float[]) e1,
                                                                                (float[]) e2 ) : (e1 instanceof double[] && e2 instanceof double[]) ? equals( (double[]) e1,
                                                                                (double[]) e2 ) : e1.equals( e2 );

            if ( !eq ) return false;
        }
        return true;
    }

    // Equality Testing

    public static boolean equals(long[] a,
                                 long[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(int[] a,
                                 int[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(short[] a,
                                 short a2[]) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(char[] a,
                                 char[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(byte[] a,
                                 byte[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(boolean[] a,
                                 boolean[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(double[] a,
                                 double[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(float[] a,
                                 float[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static boolean equals(Object[] a,
                                 Object[] a2) {
        return java.util.Arrays.equals( a,
                                        a2 );
    }

    public static List<Integer> asList(int[] ints) {
        List<Integer> list = new ArrayList<Integer>(ints.length);
        for ( int i : ints ) {
            list.add( i );
        }
        return list;
    }

    public static int[] toIntArray(List<Integer> list) {
        int[] ints = new int[list.size()];
        for ( int i = 0; i < list.size(); i++ ) {
            ints[i] = list.get( i );
        }
        return ints;
    }
}


/*
 * 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.actions;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.webdav.IResponse;
import org.guvnor.tools.Activator;
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.WebDavClientFactory;
import org.guvnor.tools.utils.webdav.WebDavException;
import org.guvnor.tools.utils.webdav.WebDavServerCache;
import org.guvnor.tools.views.ResourceHistoryView;
import org.guvnor.tools.views.model.TreeObject;

/**
 * Shows the revision history for a given resource.
 */
public class ShowHistoryAction implements IObjectActionDelegate {

    private IFile selectedFile;
    private TreeObject selectedNode;
    private GuvnorMetadataProps props;

    public ShowHistoryAction() {
        super();
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
     */
    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
     */
    public void run(IAction action) {
        String repositoryLoc = null;
        String fullPath = null;

        if (selectedNode != null) {
            repositoryLoc = selectedNode.getGuvnorRepository().getLocation();
            fullPath = selectedNode.getFullPath();
        } else {
            if (selectedFile == null
               || props == null) {
                return;
            }
            repositoryLoc = props.getRepository();
            fullPath = props.getFullpath();
        }

        IResponse response = null;
        try {
            IWebDavClient client = WebDavServerCache.getWebDavClient(repositoryLoc);
            if (client == null) {
                client = WebDavClientFactory.createClient(new URL(repositoryLoc));
                WebDavServerCache.cacheWebDavClient(repositoryLoc, client);
            }
            InputStream ins = null;
            try {
                response = client.getResourceVersions(fullPath);
                ins = response.getInputStream();
            } catch (WebDavException wde) {
                if (wde.getErrorCode() != IResponse.SC_UNAUTHORIZED) {
                    // If not an authentication failure, we don't know what to do with it
                    throw wde;
                }
                boolean retry = PlatformUtils.getInstance().
                                    authenticateForServer(repositoryLoc, client);
                if (retry) {
                    response = client.getResourceVersions(fullPath);
                    ins = response.getInputStream();
                }
            }
            if (ins != null) {
                Properties verProps = new Properties();
                verProps.load(ins);
                ResourceHistoryView view = PlatformUtils.getResourceHistoryView();
                if (view != null) {
                    view.setEntries(repositoryLoc, fullPath, verProps);
                }
            }
        } catch (Exception e) {
            Activator.getDefault().displayError(IStatus.ERROR, e.getMessage(), e, true);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException ioe) {
                    Activator.getDefault().writeLog(IStatus.ERROR, ioe.getMessage(), ioe);
                }
            }
        }
    }

    /*
     *     (non-Javadoc)
     * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
     */
    public void selectionChanged(IAction action, ISelection selection) {
        // Reset state to default
        selectedFile = null;
        selectedNode = null;
        props = null;
        action.setEnabled(false);

        if (!(selection instanceof IStructuredSelection)) {
            return;
        }

        IStructuredSelection sel = (IStructuredSelection)selection;
        if (sel.size() != 1) {
            return;
        }

        if (sel.getFirstElement() instanceof IFile) {
            try {
                props = GuvnorMetadataUtils.getGuvnorMetadata((IFile)sel.getFirstElement());
                if (props != null) {
                    selectedFile = (IFile)sel.getFirstElement();
                    action.setEnabled(true);
                }
            } catch (Exception e) {
                Activator.getDefault().writeLog(IStatus.ERROR, e.getMessage(), e);
            }
        }
        if (sel.getFirstElement() instanceof TreeObject) {
            if (((TreeObject)sel.getFirstElement()).getNodeType() == TreeObject.Type.RESOURCE) {
                selectedNode = (TreeObject)sel.getFirstElement();
                action.setEnabled(true);
            }
        }
    }
}


/*
 * 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.reteoo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.drools.core.common.BaseNode;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.reteoo.EntryPointNode;
import org.drools.core.reteoo.LeftTupleSource;
import org.drools.core.reteoo.ObjectSource;
import org.drools.core.reteoo.ObjectTypeNode;
import org.drools.core.reteoo.Rete;
import org.drools.core.util.ObjectHashMap;
import org.drools.core.util.ReflectiveVisitor;
import org.drools.eclipse.editors.rete.model.Connection;
import org.drools.eclipse.editors.rete.model.ReteGraph;

/**
 * Produces a graph in GraphViz DOT format.
 *
 * @see http://www.research.att.com/sw/tools/graphviz/
 * @see http://www.pixelglow.com/graphviz/
 */
public class ReteooVisitor extends ReflectiveVisitor {

    private static final String PACKAGE_NAME = "org.drools.eclipse.reteoo.";

    /**
     * Keeps track of visited JoinNode DOT IDs. This mapping allows the visitor
     * to recognize JoinNodes it has already visited and as a consequence link
     * existing nodes back together. This is vital to the Visitor being able to
     * link two JoinNodeInputs together through their common JoinNode.
     */
    private final Map<String, BaseVertex> visitedNodes = new HashMap<String, BaseVertex>();

    private ReteGraph           graph;

    private BaseVertex          rootVertex;

    private BaseVertex          parentVertex;

    /**
     * Constructor.
     */
    public ReteooVisitor(final ReteGraph graph) {
        this.graph = graph;
    }

    public ReteGraph getGraph() {
        return this.graph;
    }

    public BaseVertex getRootVertex() {
        return this.rootVertex;
    }

    /**
     * RuleBaseImpl visits its Rete.
     */
    public void visitInternalKnowledgeBase(final InternalKnowledgeBase ruleBase) {
        visit( (ruleBase).getRete() );
    }

    /**
     * Rete visits each of its ObjectTypeNodes.
     */
    public void visitRete(final Rete rete) {
        this.rootVertex = (ReteVertex) this.visitedNodes.get( dotId( rete ) );
        if ( this.rootVertex == null ) {
            this.rootVertex = new ReteVertex( rete );
            this.visitedNodes.put( dotId( rete ),
                                   this.rootVertex );
        }

        this.graph.addChild( this.rootVertex );
        this.parentVertex = this.rootVertex;

        for( EntryPointNode node : rete.getEntryPointNodes().values() ) {
            visit( node );
        }
    }

    public void visitBaseNode(final BaseNode node) {
        BaseVertex vertex = this.visitedNodes.get( dotId( node ) );
        if ( vertex == null ) {
            try {
                String name = node.getClass().getName();
                name = name.substring( name.lastIndexOf( '.' ) + 1 ) + "Vertex";
                final Class<?> clazz = Class.forName( PACKAGE_NAME + name );
                vertex = (BaseVertex) clazz.getConstructor( new Class[]{node.getClass()} ).newInstance( new Object[]{node} );
            } catch ( final Exception e ) {
                throw new RuntimeException( "problem visiting vertex " + node.getClass().getName(),
                                            e );
            }
            this.graph.addChild( vertex );
            this.visitedNodes.put( dotId( node ),
                                   vertex );

            new Connection( this.parentVertex,
                            vertex );

            final BaseVertex oldParentVertex = this.parentVertex;
            this.parentVertex = vertex;

            List<?> list = null;
            if ( node instanceof EntryPointNode ) {
                list = new ArrayList<ObjectTypeNode>( ((EntryPointNode) node).getObjectTypeNodes().values() );
            } else if ( node instanceof ObjectSource) {
                list = Arrays.asList( ((ObjectSource) node).getObjectSinkPropagator().getSinks() );
            } else if ( node instanceof LeftTupleSource) {
                list = Arrays.asList( ((LeftTupleSource) node).getSinkPropagator().getSinks() );
            }

            if ( list != null ) {
                for ( final java.util.Iterator<?> it = list.iterator(); it.hasNext(); ) {
                    final Object nextNode = it.next();
                    visitNode( nextNode );
                }
            }
            this.parentVertex = oldParentVertex;
        } else {
            new Connection( this.parentVertex,
                            vertex );
        }
    }

    /**
     * Helper method to ensure nodes are not visited more than once.
     */
    private void visitNode(final Object node) {
        Object realNode = node;
        if ( node instanceof ObjectHashMap.ObjectEntry ) {
            ObjectHashMap.ObjectEntry entry = (ObjectHashMap.ObjectEntry) node;
            realNode = entry.getValue();
        }
        visit( realNode );
    }

    /**
     * The identity hashCode for the given object is used as its unique DOT
     * identifier.
     */
    private static String dotId(final Object object) {
        return Integer.toHexString( System.identityHashCode( object ) ).toUpperCase();
    }

}


/*
 * 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.*;

/**
 * An element editor for the WebDAV propertyupdate element. See RFC2518
 * section 12.13 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 Prop
 */
public class PropertyUpdate extends ElementEditor {
    /**
     * An editor for a generic element that is a child of a WebDAV prop
     * element, which, in turn, is a child of a WebDAV set or remove
     * element.
     */
    public class Directive extends ElementEditor {

        /**
         * Creates a new editor on the given element.
         *
         * @param element a generic element
         * @throws        MalformedElementException if there is reason
         *                to believe that this editor's underlying
         *                element is not well formed
         */
        public Directive(Element element) throws MalformedElementException {
            super(element);
            Node parent = element.getParentNode();
            ensureDAVElement(parent, "prop", Policy.bind("ensure.expectingPropElmt")); //$NON-NLS-1$ //$NON-NLS-2$
            Node grandparent = parent.getParentNode();
            ensure(isDAVElement(grandparent, "remove") || isDAVElement(grandparent, "set"), //$NON-NLS-1$ //$NON-NLS-2$
                    Policy.bind("ensure.expectingRemoveOrSetElmt")); //$NON-NLS-1$
        }

        /**
         * Returns this editor's underlying element, which may be any
         * generic element.
         *
         * @return this editor's underlying element
         */
        public Element getProperty() throws MalformedElementException {
            return root;
        }

        /**
         * Returns true if this directive's property
         * decends from a WebDAV remove element and false
         * if it decends from a WebDAV set element.
         *
         * @return a boolean indicating whether this directive is a
         *           remove or not
         * @throws MalformedElementException if there is reason to
         *         believe that this editor's underlying element is not
         *         well formed
         */
        public boolean isRemove() throws MalformedElementException {
            Node parent = root.getParentNode();
            ensureDAVElement(parent, "prop", Policy.bind("ensure.expectingPropElmt")); //$NON-NLS-1$ //$NON-NLS-2$
            Node grandparent = parent.getParentNode();
            return isDAVElement(grandparent, "remove"); //$NON-NLS-1$
        }

        /**
         * Returns true if this directive's property
         * decends from a WebDAV set element and false
         * if it decends from a WebDAV remove element.
         *
         * @return a boolean indicating whether this directive is a
         *           set or not
         * @throws MalformedElementException if there is reason to
         *         believe that this editor's underlying element is not
         *         well formed
         */
        public boolean isSet() throws MalformedElementException {
            Node parent = root.getParentNode();
            ensureDAVElement(parent, "prop", Policy.bind("ensure.expectingPropElmt")); //$NON-NLS-1$ //$NON-NLS-2$
            Node grandparent = parent.getParentNode();
            return isDAVElement(grandparent, "set"); //$NON-NLS-1$
        }
    }

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

    /**
     * Adds a remove to the given propertyupdate and returns an editor on
     * its prop.
     *
     * @return an editor on a new prop
     */
    public Prop addRemove() {
        Element remove = appendChild(root, "remove"); //$NON-NLS-1$
        Element prop = appendChild(remove, "prop"); //$NON-NLS-1$
        Prop result = null;
        try {
            result = new Prop(prop);
        } catch (MalformedElementException e) {
            Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
        }
        return result;
    }

    /**
     * Adds a set to the given propertyupdate and returns an editor on its
     * prop.
     *
     * @return an editor on a new prop
     */
    public Prop addSet() {
        Element set = appendChild(root, "set"); //$NON-NLS-1$
        Element prop = appendChild(set, "prop"); //$NON-NLS-1$
        try {
            return new Prop(prop);
        } catch (MalformedElementException e) {
            Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
            return null; // Never reached.
        }
    }

    /**
     * Creates a new WebDAV propertyupdate element and sets it as the root
     * of the given document. Returns an editor on the new propertyupdate
     * element. The document must not be null, and must not
     * already have a root element.
     *
     * @param document the document that will become the root of a new
     *                 propertyupdate element
     * @return         an element editor on a propertyupdate element
     */
    public static PropertyUpdate create(Document document) {
        Assert.isNotNull(document);
        Assert.isTrue(document.getDocumentElement() == null);
        Element element = create(document, "propertyupdate"); //$NON-NLS-1$
        PropertyUpdate result = null;
        try {
            result = new PropertyUpdate(element);
        } catch (MalformedElementException e) {
            Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
        }
        return result;
    }

    /**
     * Returns an Enumeration over this propertyupdate's set
     * and remove property elements.
     *
     * @return an Enumeration of
     *         PropertyUpdate.Directives
     * @throws MalformedElementException if there is reason to believe that
     *         this editor's underlying element is not well formed
     */
    public Enumeration getSetsAndRemoves() throws MalformedElementException {

        Node setOrRemove = getFirstChild(root, new String[] {"remove", "set"}); //$NON-NLS-1$ //$NON-NLS-2$
        ensureNotNull(Policy.bind("ensure.missingRemoveOrSetElmt"), setOrRemove); //$NON-NLS-1$
        Node property = null;

        while (setOrRemove != null && property == null) {
            Node prop = getFirstChild((Element) setOrRemove, "prop"); //$NON-NLS-1$
            ensureNotNull(Policy.bind("ensure.missingPropElmt"), prop); //$NON-NLS-1$
            property = getChildElement((Element) prop, true);

            if (property == null)
                setOrRemove = getNextSibling((Element) setOrRemove, new String[] {"remove", "set"}); //$NON-NLS-1$ //$NON-NLS-2$
        }

        final Node a = setOrRemove;
        final Node c = property;

        Enumeration e = new Enumeration() {
            Node currentSetOrRemove = a;
            Node currentProperty = c;

            public boolean hasMoreElements() {

                return currentProperty != null;
            }

            public Object nextElement() {

                if (!hasMoreElements())
                    throw new NoSuchElementException();
                Directive result = null;
                try {
                    result = new Directive((Element) currentProperty);
                } catch (MalformedElementException ex) {
                    Assert.isTrue(false, Policy.bind("assert.internalError")); //$NON-NLS-1$
                }
                currentProperty = getNextSibling((Element) currentProperty);
                while (currentSetOrRemove != null && currentProperty == null) {
                    currentSetOrRemove = getNextSibling((Element) currentSetOrRemove, new String[] {"remove", "set"}); //$NON-NLS-1$ //$NON-NLS-2$
                    if (currentSetOrRemove != null) {
                        Node prop = getFirstChild((Element) currentSetOrRemove, "prop"); //$NON-NLS-1$
                        if (prop != null)
                            currentProperty = getChildElement((Element) prop, true);
                    }
                }
                return result;
            }
        };

        return e;
    }
}


package org.kie.eclipse.navigator.view.actions.dialogs;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import com.eclipsesource.json.JsonObject;

public abstract class AbstractKieRequestDialog extends TitleAreaDialog {

	protected JsonObject properties = new JsonObject();
	protected Button okButton;
	protected Composite errorComposite;
	protected Label errorText;
	protected IKieRequestValidator validator;
	private String title;

	protected abstract void createFields(Composite parent);

	public AbstractKieRequestDialog(Shell shell, String title, IKieRequestValidator validator) {
		super(shell);
		this.validator = validator;
		this.title = title;
		// We don't really provide help, the help toolbar is used as an
		// error message field which includes an image and text label.
		// This is better than the default TitleAreaDialog behavior of
		// overwriting the description with an error message.
		// See the createHelpControl()} and setErrorMessage() overrides

        setHelpAvailable(true);
	}

	public JsonObject getResult() {
		return properties;
	}

    /* (non-Javadoc)
     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
     */
	@Override
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText(title);
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.TitleAreaDialog#createContents(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createContents(Composite parent) {
        Control contents = super.createContents(parent);
        setTitle(title);
        validate();
        return contents;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite parentComposite = (Composite)super.createDialogArea(parent);
		Composite composite = new Composite(parentComposite, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(new GridLayout(3,false));
		composite.setFont(parent.getFont());
		createFields(composite);
		return parentComposite;
	}

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.TrayDialog#createHelpControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Control createHelpControl(Composite parent) {
        ((GridLayout) parent.getLayout()).numColumns++;
        errorComposite = new Composite(parent, SWT.NONE);
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        errorComposite.setLayoutData(gd);
        errorComposite.setLayout(new GridLayout(2, false));
    	Label errorImage = new Label(errorComposite, SWT.NONE);
    	errorImage.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
    	errorImage.setImage(JFaceResources.getImage(DLG_IMG_TITLE_ERROR));

    	errorText = new Label(errorComposite, SWT.NONE);
    	gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
    	errorText.setLayoutData(gd);
    	errorText.setText("");
    	return errorComposite;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.TitleAreaDialog#setErrorMessage(java.lang.String)
	 */
	@Override
	public void setErrorMessage(String newErrorMessage) {
		if (errorComposite!=null && !errorComposite.isDisposed()) {
			if (newErrorMessage==null || newErrorMessage.isEmpty()) {
				errorComposite.setVisible(false);
				((GridData)errorComposite.getLayoutData()).exclude = true;
				errorText.setText("");
			}
			else {
				errorComposite.setVisible(true);
				((GridData)errorComposite.getLayoutData()).exclude = false;
				errorText.setText(newErrorMessage);
			}
			errorText.getParent().getParent().layout();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean)
	 */
	@Override
	protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
		Button button = super.createButton(parent, id, label, defaultButton);
		if (id==IDialogConstants.OK_ID)
			okButton = button;
		return button;
	}

	protected void validate() {
		String msg = null;
		if (validator!=null && (msg = validator.isValid(properties))!=null) {
			setErrorMessage(msg);
			setDialogComplete(false);
		}
		else {
			setErrorMessage(null);
			setDialogComplete(true);
		}
	}

    protected void setDialogComplete(boolean value) {
        okButton.setEnabled(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.eclipse.webdav.client;

import org.eclipse.webdav.*;
import org.eclipse.webdav.dom.QualifiedName;
import org.eclipse.webdav.dom.QualifiedNameImpl;
import org.eclipse.webdav.internal.kernel.*;
import org.w3c.dom.Document;

/**
 * <b>Note:</b> 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.
 */
public class WebDAVFactory implements ILocatorFactory, IContextFactory, IDocumentFactory {

    public static IContextFactory contextFactory = new ContextFactory();
    public static IDocumentFactory documentFactory = new DocumentFactory();
    public static ILocatorFactory locatorFactory = new LocatorFactory();

    /**
     * WebDavFactory constructor comment.
     */
    public WebDAVFactory() {
        super();
    }

    public IContext newContext() {
        return contextFactory.newContext();
    }

    public IContext newContext(IContext baseContext) {
        return contextFactory.newContext(baseContext);
    }

    public Document newDocument() {
        return documentFactory.newDocument();
    }

    public ILocator newLocator(String resourceURL) {
        return locatorFactory.newLocator(resourceURL);
    }

    /**
     * Answer a new resource locator that identifies a particular
     * server resource by it's URL and label.
     *
     * @param resourceURL the URL of the resource.
     * @param label the version label of the resource.
     * @return the Locator to the resource.
     */
    public ILocator newLocator(String resourceURL, String label) {
        return locatorFactory.newLocator(resourceURL, label);
    }

    public QualifiedName newQualifiedName(String qualifier, String localName) {
        return new QualifiedNameImpl(qualifier, localName);
    }

    public ILocator newStableLocator(String resourceURL) {
        return locatorFactory.newStableLocator(resourceURL);
    }
}


/*
 * 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;

import org.drools.eclipse.editors.completion.DefaultCompletionProcessor;
import org.drools.eclipse.editors.completion.RuleCompletionProcessor;
import org.drools.eclipse.editors.scanners.DRLPartionScanner;
import org.drools.eclipse.editors.scanners.DRLScanner;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
import org.eclipse.jface.text.hyperlink.MultipleHyperlinkPresenter;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.reconciler.MonoReconciler;
import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.source.DefaultAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.graphics.RGB;

/**
 * Source viewer config wires up the syntax highlighting, partitioning
 * and content assistance.
 */
public class DRLSourceViewerConfig extends SourceViewerConfiguration {

    private DRLScanner scanner;

    private AbstractRuleEditor editor;

    public DRLSourceViewerConfig(AbstractRuleEditor editor) {
        this.editor = editor;
    }

    protected AbstractRuleEditor getEditor() {
        return editor;
    }

    protected DRLScanner getScanner() {
        if (scanner == null) {
            scanner = new DRLScanner();
        }
        return scanner;
    }

    /**
     * Define reconciler - this has to be done for each partition.
     * Currently there are 3 partitions, Inside rule, outside rule and inside comment.
     */
    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
        PresentationReconciler reconciler = new PresentationReconciler();

        //bucket partition... (everything else outside a rule)
        DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getScanner());
        reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
        reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

        //inside a rule partition
        dr = new DefaultDamagerRepairer(getScanner());
        reconciler.setDamager(dr, DRLPartionScanner.RULE_PART_CONTENT);
        reconciler.setRepairer(dr, DRLPartionScanner.RULE_PART_CONTENT);

        //finally, inside a multi line comment.
        dr = new DefaultDamagerRepairer(new SingleTokenScanner(
                new TextAttribute(ColorManager.getInstance().getColor(
                        ColorManager.SINGLE_LINE_COMMENT))));
        reconciler.setDamager(dr, DRLPartionScanner.RULE_COMMENT);
        reconciler.setRepairer(dr, DRLPartionScanner.RULE_COMMENT);

        return reconciler;
    }

    /**
     * Single token scanner, used for scanning for multiline comments mainly.
     */
    static class SingleTokenScanner extends BufferedRuleBasedScanner {
        public SingleTokenScanner(TextAttribute attribute) {
            setDefaultReturnToken(new Token(attribute));
        }
    }

    /**
     * Get the appropriate content assistance, for each partition.
     */
    public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
        ContentAssistant assistant = new ContentAssistant();
        //setup the content assistance, which is
        //sensitive to the partition that it is in.
        assistant.setContentAssistProcessor(
            new DefaultCompletionProcessor(editor), IDocument.DEFAULT_CONTENT_TYPE);
        assistant.setContentAssistProcessor(
            new RuleCompletionProcessor(editor), DRLPartionScanner.RULE_PART_CONTENT);
        assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
        return assistant;
    }

    public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
        return DRLPartionScanner.LEGAL_CONTENT_TYPES;
    }

    public IReconciler getReconciler(ISourceViewer sourceViewer) {
        MonoReconciler reconciler = null;
        if (sourceViewer != null) {
            reconciler = new MonoReconciler(
                new DRLReconcilingStrategy(sourceViewer, editor), false);
            reconciler.setDelay(500);
            reconciler.setProgressMonitor(new NullProgressMonitor());
        }
        return reconciler;
    }

    public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
        return new DefaultAnnotationHover();
    }

    public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
        return new DefaultAnnotationHover();
    }

    @Override
    public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
      IHyperlinkDetector[] detectors = super.getHyperlinkDetectors(sourceViewer);
      if(detectors==null) {
        detectors = new IHyperlinkDetector[0];
      }

      IHyperlinkDetector[] drlDetectors = new IHyperlinkDetector[detectors.length + 1];
      DRLHyperlinkDetector detector =  new DRLHyperlinkDetector(editor);
      drlDetectors[0] = detector;
      System.arraycopy(detectors, 0, drlDetectors, 1, detectors.length);

      return drlDetectors;
    }

	public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) {
		return new MultipleHyperlinkPresenter(new RGB(0, 0, 255));
	}
}