Package org.openquark.gems.client

Source Code of org.openquark.gems.client.FunctionalAgentGem

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* FunctionalAgentGem.java
* Creation date: (10/18/00 1:03:35 PM)
* By: Luke Evans
*/
package org.openquark.gems.client;

import java.util.List;

import org.openquark.cal.compiler.CALDocComment;
import org.openquark.cal.compiler.CompositionNode;
import org.openquark.cal.compiler.FieldName;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.compiler.TypeExpr;
import org.openquark.cal.metadata.ArgumentMetadata;
import org.openquark.cal.metadata.FunctionalAgentMetadata;
import org.openquark.cal.services.CALPersistenceHelper;
import org.openquark.cal.services.CALWorkspace;
import org.openquark.cal.services.GemEntity;
import org.openquark.util.xml.BadXMLDocumentException;
import org.openquark.util.xml.XMLPersistenceHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
* A FunctionalAgentGem is a named gem which can represent a supercombinator, data constructor, or class method.
* Creation date: (10/18/00 1:03:35 PM)
* @author Luke Evans
*/
public class FunctionalAgentGem extends Gem implements CompositionNode.GemEntityNode, NamedGem {

    /** The gemEntity that this Gem represents */
    private GemEntity gemEntity;

    /**
     * Construct a FunctionalAgentGem from a Supercombinator and its type.
     * @param gemEntity the GemEntity from which to construct the gem.
     */
    public FunctionalAgentGem(GemEntity gemEntity) {
        super(gemEntity.getTypeArity());
        this.gemEntity = gemEntity;

        // Some of the supplied argument names might be null, but that's OK because
        // the input metadata will automatically use a default name if it's given a null value.
        // NOTE: We want any gems created with names from code or from metadata to consider those names
        //       as NOT being user saved names. This works fine here as a new input name object will be
        //       created with an initial name of whatever we supply.
        FunctionalAgentMetadata metadata = gemEntity.getMetadata(GemCutter.getLocaleFromPreferences());
        ArgumentMetadata[] argMetadata = metadata.getArguments();
        int numNamedArgs = gemEntity.getNNamedArguments();
        CALDocComment caldoc = gemEntity.getFunctionalAgent().getCALDocComment();
       
        for (int i = 0, numInputs = getNInputs(); i < numInputs; i++) {
            PartInput inputPart = getInputPart(i);
           
            String nameFromEntity = i < numNamedArgs ? gemEntity.getNamedArgument(i) : null;
            String displayName = i < argMetadata.length ? argMetadata[i].getDisplayName() : null;
            FieldName caldocName = (caldoc != null && i < caldoc.getNArgBlocks()) ? caldoc.getNthArgBlock(i).getArgName() : null;
           
            String originalName;
            if (displayName != null) {
                originalName = displayName;
            } else if (caldocName != null && caldocName instanceof FieldName.Textual) {
                // if the CALDoc name is present, we will use it instead of the name from the entity
                // since the CALDoc name is specified by the user, where the name from the entity
                // may have come from an automatically extracted parameter name for a foreign function
                originalName = caldocName.getCalSourceForm();
            } else if (nameFromEntity != null) {
                originalName = nameFromEntity;
            } else {
                originalName = null;
            }
           
            inputPart.setOriginalInputName(originalName);
            inputPart.setArgumentName(new ArgumentName(originalName));
        }
       
        setPartTypes(gemEntity.getTypeExpr().getTypePieces());
    }  
   
    /**
     * Construct an empty gem.
     * A gem created using this constructor is appropriate for use in deserialization.
     */
    private FunctionalAgentGem() {
        // Initialize with no input parts.
        super(0);
    }

    /**
     * Get the qualified name of the Gem (the name of the underlying supercombinator)
     * @return QualifiedName the name
     */
    public QualifiedName getName() {
        return gemEntity.getName();
    }

    /**
     * Get the unqualified name of the Gem (the name of the underlying supercombinator)
     * @return The node's unqualified name.
     */
    public String getUnqualifiedName(){
        return gemEntity.getName().getUnqualifiedName();
    }
   
    /**
     * Return the entity represented by this gem
     * @return GemEntity the entity represented by this gem
     */
    public final GemEntity getGemEntity() {
        return gemEntity;
    }

    /**
     * Update the entity represented by this FunctionalAgentGem.
     * This method is used when the program is recompiled, and entities are regenerated.
     * @param workspace the workspace from which to reload the entity.
     */
    void updateGemEntity(CALWorkspace workspace) throws GemEntityNotPresentException {
        updateGemEntity(workspace, gemEntity.getName());       
    }
   
    /**
     * Update the entity represented by this FunctionalAgentGem.
     * This method is used when the program is recompiled, and entities are regenerated.
     * @param workspace the workspace from which to reload the entity.
     * @param entityName If the gem has been renamed, this should be the new name of the gem.
     */
    void updateGemEntity(CALWorkspace workspace, QualifiedName entityName) throws GemEntityNotPresentException  {       
        // TODO: we should also check/morph for sc arity and type changes, and revalidate any connections.
        GemEntity newEntity = workspace.getGemEntity(entityName);
        QualifiedName oldName = gemEntity.getName();
        if (newEntity == null) {
            throw new GemEntityNotPresentException(gemEntity.getName());
        }
        this.gemEntity = newEntity;
       
        if (oldName == entityName){
            nameChangeListener.nameChanged(new NameChangeEvent(this, oldName.getQualifiedName()));
        }
    }

    /**
     * Store the local type information for this Gem's parts. 
     * The order is: inputs first (in order), then output (if any).
     * @param tes the types
     */
    private final void setPartTypes(TypeExpr[] tes) {
        // The output
        PartOutput outputPart = getOutputPart();
        if (outputPart != null) {
            int last = tes.length - 1;
            getOutputPart().setType(tes[last]);
        }

        // The inputs (if we have any)
        int numInputs = getNInputs();
        for (int i = 0; i < numInputs; i++) {
            getInputPart(i).setType(tes[i]);
        }   
    }

    /**
     * Describe this Gem
     * @return the description
     */
    @Override
    public String toString() {
        return getName().getQualifiedName();
    }

    /*
     * Methods supporting XMLPersistable                 ********************************************
     */

    /**
     * {@inheritDoc}
     */
    @Override
    public void saveXML(Node parentNode, GemContext gemContext) {
       
        Document document = (parentNode instanceof Document) ? (Document)parentNode : parentNode.getOwnerDocument();

        // Create the functional agent gem element
        Element resultElement = document.createElementNS(GemPersistenceConstants.GEM_NS, GemPersistenceConstants.FUNCTIONAL_AGENT_GEM_TAG);
        resultElement.setPrefix(GemPersistenceConstants.GEM_NS_PREFIX);
        parentNode.appendChild(resultElement);

        // Add info for the superclass gem.
        super.saveXML(resultElement, gemContext);


        // Now add FunctionalAgentGem-specific info

        // Add an element for the name.
        Element nameElement = CALPersistenceHelper.qualifiedNameToElement(getName(), document);
        resultElement.appendChild(nameElement);
    }

    /**
     * Create a new FunctionalAgentGem and loads its state from the specified XML element.
     * @param gemElement Element the element representing the structure to deserialize.
     * @param gemContext the context in which the gem is being instantiated.
     * @param workspace the workspace from which to retrieve functional agents by name
     * @return FunctionalAgentGem
     * @throws BadXMLDocumentException
     */
    public static FunctionalAgentGem getFromXML(Element gemElement, GemContext gemContext, CALWorkspace workspace) throws BadXMLDocumentException {
        FunctionalAgentGem gem = new FunctionalAgentGem();
        gem.loadXML(gemElement, gemContext, workspace);
        return gem;
    }

    /**
     * Load this object's state.
     * @param gemElement the element representing the structure to deserialize.
     * @param gemContext the context in which the gem is being instantiated.
     * @param workspace the program from which to retrieve functional agents by name
     */
    void loadXML(Element gemElement, GemContext gemContext, CALWorkspace workspace) throws BadXMLDocumentException {

        XMLPersistenceHelper.checkTag(gemElement, GemPersistenceConstants.FUNCTIONAL_AGENT_GEM_TAG);
        XMLPersistenceHelper.checkPrefix(gemElement, GemPersistenceConstants.GEM_NS_PREFIX);

        List<Element> childElems = XMLPersistenceHelper.getChildElements(gemElement);

        // Get info for the underlying gem.
        Element superGemElem = (childElems.size() < 1) ? null : (Element) childElems.get(0);
        XMLPersistenceHelper.checkIsElement(superGemElem);
        super.loadXML(superGemElem, gemContext);

        // Get the name
        Element nameElem = (childElems.size() < 2) ? null : (Element) childElems.get(1);
        XMLPersistenceHelper.checkIsElement(nameElem);
        QualifiedName gemName = CALPersistenceHelper.elementToQualifiedName(nameElem);
       
        // Get the supercombinator and its type
        this.gemEntity = workspace.getGemEntity(gemName);
        if (this.gemEntity == null) {
            XMLPersistenceHelper.handleBadDocument(nameElem, "No functional agent found for " + gemName);
        }

        // Set the part types if any
        TypeExpr scType = gemEntity.getTypeExpr();
        if (scType != null) {
           
            // Check that the entity has the right number of applications.
            if (scType.getArity() != getNInputs()) {
                XMLPersistenceHelper.handleBadDocument(nameElem,
                                                             "Error loading " + gemName + ".  Functional agent has " +
                                                               scType.getArity() + " inputs, saved with " + getNInputs() + ".");
            }
           
            setPartTypes(scType.getTypePieces());
        }
    }
}
TOP

Related Classes of org.openquark.gems.client.FunctionalAgentGem

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