Package org.openquark.gems.client

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

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


/*
* GemCutterPersistenceManager.java
* Creation date: Nov 7, 2003
* By: Frank Worsley
*/
package org.openquark.gems.client;

import java.util.Set;

import org.openquark.cal.compiler.AdjunctSource;
import org.openquark.cal.compiler.CALSourceGenerator;
import org.openquark.cal.compiler.CompilerMessageLogger;
import org.openquark.cal.compiler.MessageLogger;
import org.openquark.cal.compiler.ModuleName;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.compiler.Scope;
import org.openquark.cal.compiler.SourceModel;
import org.openquark.cal.compiler.TypeExpr;
import org.openquark.cal.metadata.FunctionMetadata;
import org.openquark.cal.services.CALFeatureName;
import org.openquark.cal.services.GemDesign;
import org.openquark.cal.services.GemEntity;
import org.openquark.cal.services.Status;
import org.openquark.util.xml.BadXMLDocumentException;
import org.openquark.util.xml.NamespaceInfo;
import org.openquark.util.xml.XMLPersistenceHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
* This class takes care of loading and saving GemCutter gem designs and definitions.
* @author Frank Worsley
*/
public class GemCutterPersistenceManager {

    /** The GemCutter this manager is for. */
    private final GemCutter gemCutter;
   
    /**
     * Constructor for a new GemCutterPersistenceManager.
     * @param gemCutter the GemCutter this manager is for
     */
    GemCutterPersistenceManager(GemCutter gemCutter) {
       
        if (gemCutter == null) {
            throw new NullPointerException();
        }
       
        this.gemCutter = gemCutter;
    }

    /**
     * Attach the saved form of this object as a child XML node.
     * @param parentNode the node that will be the parent of the generated XML. 
     *   The generated XML will be appended as a subtree of this node. 
     *   Note: parentNode must be a node type that can accept children (eg. an Element or a DocumentFragment)
     */
    private void saveXML(Node parentNode) {
       
        Document document = (parentNode instanceof Document) ? (Document)parentNode : parentNode.getOwnerDocument();

        // Create the GemCutter element, with the appropriate default namespace
        Element resultElement = document.createElementNS(GemPersistenceConstants.GEMS_NS, GemPersistenceConstants.GEMCUTTER_TAG);
        parentNode.appendChild(resultElement);

        // Declare gem namespace and schema.
        NamespaceInfo gemNSInfo = Gem.getNamespaceInfo();
        XMLPersistenceHelper.attachNamespaceAndSchema(document, gemNSInfo, GemPersistenceConstants.GEMS_SCHEMA_LOCATION, GemPersistenceConstants.GEMS_NS);

        // Add info for the tabletop
        gemCutter.getTableTop().saveXML(resultElement);

        // Now add GemCutter-specific info
        // For now, there isn't any.
    }

    /**
     * Restore the contents of this object from an element.
     * @param element the element at the head of the subtree which represents the object to reconstruct.
     * @param loadStatus the ongoing status of the load.
     */
    private void loadXML(Element element, Status loadStatus){

        try {
            XMLPersistenceHelper.checkTag(element, GemPersistenceConstants.GEMCUTTER_TAG);
           
            Node tableTopNode = element.getFirstChild();
            XMLPersistenceHelper.checkIsElement(tableTopNode);
   
            // Just call the tabletop to restore itself.
            gemCutter.getTableTop().loadXML((Element) tableTopNode, gemCutter.getPerspective(), loadStatus);
           
            // TODOEL: write a schema and validate against it

        } catch (BadXMLDocumentException bxde) {
            loadStatus.add(new Status(Status.Severity.ERROR, GemCutter.getResourceString("SOM_GCLoadFailure"), bxde));
        }
    }

    /**
     * Save a specific Gem.
     * @param gemToSave the Gem to save
     * @param scope the visibility of the gem to save
     * @return the status of the save
     */
    Status saveGem(CollectorGem gemToSave, Scope scope) {

        if (gemToSave == null) {
            throw new NullPointerException();
        }
       
        // TODO
        // Right now this either replaces the gem text if the gem is defined and the appropriate markers
        // can be found, or fails. If save succeeds, the design view is also written out to an XML file.

        // Determine the name of the gem being saved
        QualifiedName gemName = QualifiedName.make(gemCutter.getWorkingModuleName(), gemToSave.getUnqualifiedName());

        // Get the gem definition.
        String gemDefinition = getGemDefinition(gemToSave, scope);
       
        // Get the gem metadata as functional agent metadata.
        CALFeatureName gemEntityFeatureName = CALFeatureName.getFunctionFeatureName(gemName);

        FunctionMetadata collectorMetadata = gemToSave.getDesignMetadata();
        FunctionMetadata newGemMetadata = new FunctionMetadata(gemEntityFeatureName, collectorMetadata.getLocale());
       
        collectorMetadata.copyTo(newGemMetadata);
       
        // Get the gem design.
        Document designDocument = XMLPersistenceHelper.getEmptyDocument();
        saveXML(designDocument);
       
        Status saveStatus = gemCutter.getWorkspace().saveEntity(gemName, gemDefinition, newGemMetadata, designDocument);
       
        if (saveStatus.getSeverity() != Status.Severity.ERROR) {
            // TEMP: this is a re-entrancy hack
            gemCutter.recompileWorkspace(true);
        }
       
        return saveStatus;
    }
   
    /**
     * Obtain the CAL definition of a gem.
     * @param collectorGem the gem for which the definition should be obtained..
     * @param scope the scope of the gem.
     */
    private String getGemDefinition(CollectorGem collectorGem, Scope scope) {

        // Get the qualified name.
        String unqualifiedGemName = collectorGem.getUnqualifiedName();

        // Now get the text of the CAL definition for the gem.

        // The definition..
        SourceModel.FunctionDefn scDef = CALSourceGenerator.getFunctionSourceModel(unqualifiedGemName, collectorGem, scope);

        // TODO Display any error messages from logger?
        CompilerMessageLogger logger = new MessageLogger ();

        // The declaration..
        TypeExpr type = gemCutter.getTypeChecker().checkFunction(
            new AdjunctSource.FromSourceModel(scDef), gemCutter.getWorkingModuleName(), logger);
        String typeDeclaration = (type == null) ? null : unqualifiedGemName + " :: " + type.toString() + ";";

        StringBuilder sb = new StringBuilder();
        if (typeDeclaration != null) {
            sb.append(typeDeclaration + "\n");
        }
        sb.append(scDef + "\n");
       
        return sb.toString();
    }

    /**
     * Load a gem's design and put it on the table top.
     * @param gemEntity the entity whose design to load.
     * @param loadStatus a Status object for storing the status of the load operation
     */
    void loadGemDesign(GemEntity gemEntity, Status loadStatus) {
        GemDesign gemDesign = gemEntity.getDesign(loadStatus);
        if (gemDesign != null) {
            loadGemDesign(gemDesign, loadStatus);
        }
    }
   
    /**
     * Load a gem design and put it on the tabletop.
     * @param gemDesign the design to load.
     * @param loadStatus a Status object for storing the status of the load operation.
     */
    void loadGemDesign(GemDesign gemDesign, Status loadStatus) {
        // Switch to the module the design is from.
        QualifiedName designName = gemDesign.getDesignName();
        ModuleName moduleName = designName.getModuleName();
        if (gemCutter.getWorkspace().getMetaModule(moduleName) != null) {
            gemCutter.changeModuleAndNewTableTop(moduleName, false);
        }
       
        loadXML(gemDesign.getDesignDocument().getDocumentElement(), loadStatus);
       
        // Find the collector that was loaded on the table top.
        String unqualifiedDesignName = designName.getUnqualifiedName();
        Set<CollectorGem> collectors = gemCutter.getTableTop().getGemGraph().getCollectorsForName(unqualifiedDesignName);

        if (collectors.iterator().hasNext()) {
            CollectorGem collectorGem = collectors.iterator().next();
       
            // Find the gem in the working module with the same name
            GemEntity entity = gemCutter.getWorkspace().getGemEntity(designName);

            if (entity != null) {
                // Load the metadata for the gem and copy it to the collector
                FunctionMetadata gemMetadata = (FunctionMetadata)entity.getMetadata(GemCutter.getLocaleFromPreferences());
                collectorGem.setDesignMetadata(gemMetadata);
            } else {
                // Clear the metadata for the collector, since there is no gem entity for the design
                collectorGem.clearDesignMetadata();
            }

        } else {
            loadStatus.add(new Status(Status.Severity.ERROR, GemCutter.getResourceString("SOM_CouldntFindCollector"), null));
        }
    }
}
TOP

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

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.