Package org.openquark.cal.services

Source Code of org.openquark.cal.services.WorkspacePersistenceManager

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


/*
* WorkspacePersistenceManager.java
* Creation date: Oct 13, 2004.
* By: Edward Lam
*/
package org.openquark.cal.services;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.openquark.cal.compiler.ModuleName;
import org.openquark.util.xml.BadXMLDocumentException;
import org.openquark.util.xml.NamespaceInfo;
import org.openquark.util.xml.XMLPersistenceHelper;
import org.openquark.util.xml.XMLPersistenceHelper.DocumentConstructionException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;



/**
* This class takes care of saving and loading workspace-related resources.
* @author Edward Lam
*/
class WorkspacePersistenceManager {

    /** The workspace with which this manager is associated. */
    private final CALWorkspace workspace;

    /**
     * A simple wrapper around a vault descriptor and a string which identifies a vault type and its location.
     * @author Edward Lam
     */
    private static class VaultLocation {
       
        private final String vaultDescriptor;
        private final String locationString;

        /**
         * Constructor for a VaultLocation.
         */
        public VaultLocation(String vaultDescriptor, String locationString) {
            this.vaultDescriptor = vaultDescriptor;
            this.locationString = locationString;
        }
        /**
         * @return Returns the vaultDescriptor.
         */
        public String getVaultDescriptor() {
            return vaultDescriptor;
        }
        /**
         * @return Returns the locationString.
         */
        public String getLocationString() {
            return locationString;
        }
    }
   
    /**
     * Constructor for a WorkspacePersistenceManager.
     * @param workspace the workspace with which this manager is associated.
     */
    WorkspacePersistenceManager(CALWorkspace workspace) {
        this.workspace = workspace;
    }
   
    /**
     * Saves the workspace description to a stream.
     * @param descriptionOutputStream the stream to which to save the workspace description.
     * @param resourceInfo the info about resources in the workspace.
     */
    void saveWorkspaceDescription(OutputStream descriptionOutputStream, CALWorkspace.ResourceInfo resourceInfo) {
   
        // Convert the description into an XML document
        Document document = XMLPersistenceHelper.getEmptyDocument();

        // Attach the root document element.
        Element resultElement = document.createElementNS(WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.WORKSPACE_DESCRIPTION_TAG);
        document.appendChild(resultElement);

       
        // Just attach the component module descriptions to the top-level document root.
        ModuleName[] moduleNames = workspace.getModuleNames();
        int nModules = moduleNames.length;
        for (int i = 0; i < nModules; i++) {
            ModuleName moduleName = moduleNames[i];
            saveWorkspaceModuleDescription(resultElement, moduleName, resourceInfo);
        }
       
       
        // Attach namespace and schema info.
        XMLPersistenceHelper.attachNamespaceAndSchema(document, getNamespaceInfo(), WorkspacePersistenceConstants.WORKSPACE_DESCRIPTION_SCHEMA_LOCATION, WorkspacePersistenceConstants.WORKSPACE_NS);
   
        // Write the document to the metadata file
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(descriptionOutputStream);
        XMLPersistenceHelper.documentToXML(document, bufferedOutputStream, false);
    }
   
    /**
     * Save the workspace-related info for a module as xml.
     * @param parentNode the node to which to save the info.
     * @param moduleName the name of the module.
     * @param resourceInfo the info about resources in the workspace.
     */
    void saveWorkspaceModuleDescription(Node parentNode, ModuleName moduleName, CALWorkspace.ResourceInfo resourceInfo) {
        Document document = (parentNode instanceof Document) ? (Document) parentNode : parentNode.getOwnerDocument();

        // Attach an element for the module.
        Element moduleElement = document.createElementNS(WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.MODULE_TAG);
        parentNode.appendChild(moduleElement);
       
        // Set the name of the module as an attribute.
        moduleElement.setAttribute(WorkspacePersistenceConstants.MODULE_NAME_ATTR, moduleName.toSourceText());
       
        // Save vault info for the module.
        VaultElementInfo info = workspace.getVaultInfo(moduleName);
        saveVaultInfo(moduleElement, info);
       
        // Add module revision.
        long moduleRevision = info.getRevision();
        XMLPersistenceHelper.addLongElementNS(moduleElement, WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.MODULE_REVISION_TAG, moduleRevision);
       
        // Save info for the individual module resources.
        saveResourceInfo(moduleElement, moduleName, resourceInfo);
    }
   
    /**
     * @return the namespace info for the workspace.
     */
    static NamespaceInfo getNamespaceInfo() {
        return new NamespaceInfo(WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.WORKSPACE_NS_PREFIX);
    }
   
    /**
     * Loads a workspace description from a stream.
     * @param descriptionInputStream the stream from which to obtain the workspace description.
     */
    boolean loadWorkspaceDescription(InputStream descriptionInputStream, Status loadStatus) {
   
        try {
            InputStream bufferedInputStream = new BufferedInputStream(descriptionInputStream);
            Document descriptionDocument = XMLPersistenceHelper.documentFromXML(bufferedInputStream);
            Element documentElement = descriptionDocument.getDocumentElement();
           
            XMLPersistenceHelper.checkTag(documentElement, WorkspacePersistenceConstants.WORKSPACE_DESCRIPTION_TAG);
           
            List<Element> moduleDescriptionNodes = XMLPersistenceHelper.getChildElements(documentElement);
           
            for (final Element moduleDescriptionElement : moduleDescriptionNodes) {
                loadWorkspaceModuleDescription(moduleDescriptionElement);
            }
           
            // TODOEL: write a schema and validate against it
           
            return true;

        } catch (BadXMLDocumentException bxde) {
            loadStatus.add(new Status(Status.Severity.ERROR, "Workspace description load failure.", bxde));
       
        } catch (DocumentConstructionException ex) {
            loadStatus.add(new Status(Status.Severity.ERROR, "The workspace description file XML is invalid.", ex));
           
        } catch (Exception ex) {
            loadStatus.add(new Status(Status.Severity.ERROR, "Exception while loading workspace description.", ex));
        }
       
        return false;
    }
   
    /**
     * Load the workspace-related info for a module as xml.
     * @param moduleDescriptionElement the element describing the module's workspace-related info.
     * @throws BadXMLDocumentException
     */
    void loadWorkspaceModuleDescription(Element moduleDescriptionElement) throws BadXMLDocumentException {

        XMLPersistenceHelper.checkTag(moduleDescriptionElement, WorkspacePersistenceConstants.MODULE_TAG);
       
        String moduleNameString = moduleDescriptionElement.getAttribute(WorkspacePersistenceConstants.MODULE_NAME_ATTR);
        if (moduleNameString.equals("")) {
            String errorString = "Could not obtain module from workspace description.";
            throw new BadXMLDocumentException(moduleDescriptionElement, errorString);
        }
       
        ModuleName moduleName = ModuleName.make(moduleNameString);
       
        List<Element> childElems = XMLPersistenceHelper.getChildElements(moduleDescriptionElement);
        int nChildElems = childElems.size();

        // Get the vault info element.
        Element vaultElement = (nChildElems < 1) ? null : childElems.get(0);
        XMLPersistenceHelper.checkIsElement(vaultElement);

        // Get the module revision.
        Element moduleRevisionElement = (nChildElems < 2) ? null : childElems.get(1);
        XMLPersistenceHelper.checkTag(moduleRevisionElement, WorkspacePersistenceConstants.MODULE_REVISION_TAG);
        Integer moduleRevisionNum = XMLPersistenceHelper.getElementIntegerValue(moduleRevisionElement);
       
        if (moduleRevisionNum == null) {
            throw new BadXMLDocumentException(moduleRevisionElement, "No module revision found.");
        }
       
        // Get resource info.
        Element revisionInfoElement = (nChildElems < 3) ? null : childElems.get(2);
        XMLPersistenceHelper.checkIsElement(revisionInfoElement);
        CALWorkspace.ResourceInfo resourceInfo = loadResourceInfo(revisionInfoElement);
       
        // Update the resource info.
        workspace.updateResourceInfo(resourceInfo);

        // Get the module location.
        VaultLocation storedModuleLocation = getVaultLocation(vaultElement);
       
        // Create the vault info.
        VaultElementInfo vaultInfo = VaultElementInfo.makeBasic(storedModuleLocation.getVaultDescriptor(),
                                                          moduleName.toSourceText(),
                                                          storedModuleLocation.getLocationString(),
                                                          moduleRevisionNum.intValue());
       
        // Update the info map.
        workspace.updateVaultInfo(moduleName, vaultInfo);
    }

   /**
    * Save vault info as xml.
    * @param parentElement the element to which the info should be saved.
    * @param vaultInfo the info to save.
    */
   static void saveVaultInfo(Element parentElement, VaultElementInfo vaultInfo) {
       Document document = (parentElement instanceof Document) ? (Document) parentElement : parentElement.getOwnerDocument();

       Element vaultInfoElement = document.createElementNS(WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.VAULT_INFO_TAG);
       parentElement.appendChild(vaultInfoElement);

       // Add vault type.
       String vaultDescriptor = vaultInfo.getVaultDescriptor();
       XMLPersistenceHelper.addTextElementNS(vaultInfoElement, WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.VAULT_TYPE_TAG, vaultDescriptor);


       // Add a text element with the location.  (Note: the element will have not text if the location string is null..).
       String locationString = vaultInfo.getLocationString();
       XMLPersistenceHelper.addTextElementNS(vaultInfoElement, WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.VAULT_LOCATION_TAG, locationString);
      
   }
  
   /**
    * Load a vault location from xml.
    * @param vaultInfoElement the xml element describing the vault location.
    * @return the corresponding location, or null if there isn't any.
    * @throws BadXMLDocumentException
    */
   private static VaultLocation getVaultLocation(Element vaultInfoElement) throws BadXMLDocumentException {

       XMLPersistenceHelper.checkTag(vaultInfoElement, WorkspacePersistenceConstants.VAULT_INFO_TAG);
      
       List<Element> childElems = XMLPersistenceHelper.getChildElements(vaultInfoElement);
       int nChildElems = childElems.size();

       // Get the vault descriptor string.
       Element vaultDescriptorElement = (nChildElems < 1) ? null : childElems.get(0);
       XMLPersistenceHelper.checkIsElement(vaultDescriptorElement);
       final String vaultDescriptor = XMLPersistenceHelper.getElementStringValue(vaultDescriptorElement);
      
       // Get the vault location string.
       Element locationElement = (nChildElems < 2) ? null : childElems.get(1);
       XMLPersistenceHelper.checkIsElement(locationElement);
       final String locationString = XMLPersistenceHelper.getElementStringValue(locationElement);
      
       return new VaultLocation(vaultDescriptor, locationString);
   }
  
   /**
    * Save resource info for individual module resources.
    * @param parentElement the element to which the info should be saved.
    * @param moduleName the name of the module whose info should be saved.
    * @param resourceInfo the info to save.
    */
   static void saveResourceInfo(Element parentElement, ModuleName moduleName, CALWorkspace.ResourceInfo resourceInfo) {
       Document document = (parentElement instanceof Document) ? (Document) parentElement : parentElement.getOwnerDocument();
      
       // Attach an element to hold all the resource info.
       Element resourceInfoParentElement = document.createElementNS(WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.RESOURCE_INFO_TAG);
       parentElement.appendChild(resourceInfoParentElement);

       // Get the revision and sync time info.
       ResourceRevision.Info revisionInfo = resourceInfo.getResourceRevisionInfo();
       CALWorkspace.SyncTimeInfo syncTimeInfo = resourceInfo.getResourceSyncTimeInfo();
      
       // Get the resource types.
       Set<String> resourceTypes = new LinkedHashSet<String>();
       resourceTypes.addAll(Arrays.asList(revisionInfo.getResourceTypes()));
       resourceTypes.addAll(Arrays.asList(syncTimeInfo.getResourceTypes()));
      
       // Iterate over the resource types.
       for (final String resourceType : resourceTypes) {
           Set<ResourceRevision> resourceRevisions = revisionInfo.getResourceRevisions(resourceType);
//           Set syncTimes = syncTimeInfo.getResourceSyncTimes(resourceType);
           // TODOEL: for now, we assume that anything that has a revision also has a sync time, and vice versa.
          
           // Create the individual resource info element
           Element resourceTypeElement = document.createElementNS(WorkspacePersistenceConstants.WORKSPACE_NS, resourceType);
           resourceInfoParentElement.appendChild(resourceTypeElement);
          
           for (final ResourceRevision resourceRevision : resourceRevisions) {

               long resourceRevisionNum = resourceRevision.getRevisionNumber();
               ResourceIdentifier identifier = resourceRevision.getIdentifier();
              
               // Convert to a cal feature name..
               if (!(identifier.getFeatureName() instanceof CALFeatureName)) {
                   continue;
               }
               CALFeatureName calFeatureName = (CALFeatureName)identifier.getFeatureName();
              
               if (calFeatureName.hasModuleName() && calFeatureName.toModuleName().equals(moduleName)) {

                   // Add an element to hold the info for this feature.
                   Element featureElement = document.createElementNS(WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.RESOURCE_FEATURE_TAG);
                   resourceTypeElement.appendChild(featureElement);
   
                   // Add info for the feature.
                   // Resource name.
                   identifier.getResourceName().saveXML(featureElement);
                  
                   // Revision.
                   XMLPersistenceHelper.addLongElementNS(featureElement, WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.RESOURCE_REVISION_TAG, resourceRevisionNum);
   
                   // Sync time.
                   long resourceSyncTime = syncTimeInfo.getResourceSyncTime(identifier);
                   XMLPersistenceHelper.addLongElementNS(featureElement, WorkspacePersistenceConstants.WORKSPACE_NS, WorkspacePersistenceConstants.SYNC_TIME_TAG, resourceSyncTime);
               }
           }

       }
   }
  
   /**
    * Load the resource info from the given xml element.
    * @param resourceInfoParentElement the element from which to load resource info.
    * @return resource info from the given element.
    * @throws BadXMLDocumentException if there was an error obtaining resource info from the given element.
    */
   private static CALWorkspace.ResourceInfo loadResourceInfo(Element resourceInfoParentElement)
           throws BadXMLDocumentException {

       // Check that the parent element carries the expected tag.
       XMLPersistenceHelper.checkTag(resourceInfoParentElement, WorkspacePersistenceConstants.RESOURCE_INFO_TAG);
      
       // The list of revisions.
       List<ResourceRevision> revisionList = new ArrayList<ResourceRevision>();
      
       // The list of sync times.
       List<WorkspaceResource.SyncTime> syncTimeList = new ArrayList<WorkspaceResource.SyncTime>();
      
       // Iterate through the children.
       // There will be one for each resource type.
       List<Element> revisionInfoElems = XMLPersistenceHelper.getChildElements(resourceInfoParentElement);
       for (final Element resourceTypeElement : revisionInfoElems) {
          
           // Get the name of the element.  This will be the resource type.
           String resourceType = resourceTypeElement.getLocalName();
          
           // Get its children.  These will be the features of that type.
           List<Element> resourceTypeFeatureElems = XMLPersistenceHelper.getChildElements(resourceTypeElement);

           for (final Element featureElement : resourceTypeFeatureElems) {
               XMLPersistenceHelper.checkTag(featureElement, WorkspacePersistenceConstants.RESOURCE_FEATURE_TAG);
              
               List<Element> featureChildElems = XMLPersistenceHelper.getChildElements(featureElement);
               int nFeatureChildElems = featureChildElems.size();
              
               Element featureNameElement = (nFeatureChildElems < 1) ? null : featureChildElems.get(0);
               XMLPersistenceHelper.checkIsElement(featureNameElement);
               ResourceName resourceName = ResourceName.getResourceNameWithCALFeatureNameFromXML(featureNameElement);

               Element featureRevisionNumElement = (nFeatureChildElems < 2) ? null : featureChildElems.get(1);
               XMLPersistenceHelper.checkIsElement(featureRevisionNumElement);
               final Long featureRevisionNum = XMLPersistenceHelper.getElementLongValue(featureRevisionNumElement);
              
               if (featureRevisionNum == null) {
                   throw new BadXMLDocumentException(featureRevisionNumElement, "No feature revision found.");
               }
              
               ResourceRevision metadataRevision =
                       new ResourceRevision(new ResourceIdentifier(resourceType, resourceName), featureRevisionNum.longValue());
               revisionList.add(metadataRevision);
              
               // sync time
               Element featureSyncTimeElement = (nFeatureChildElems < 3) ? null : featureChildElems.get(2);
               XMLPersistenceHelper.checkIsElement(featureSyncTimeElement);
               final Long featureSyncTimeNum = XMLPersistenceHelper.getElementLongValue(featureSyncTimeElement);
              
               if (featureSyncTimeNum == null) {
                   throw new BadXMLDocumentException(featureSyncTimeElement, "No feature sync time found.");
               }

               WorkspaceResource.SyncTime syncTime = new WorkspaceResource.SyncTime(new ResourceIdentifier(resourceType, resourceName), featureSyncTimeNum.longValue());
               syncTimeList.add(syncTime);
           }
       }

       // Create the resource info.
       ResourceRevision.Info resourceRevisionInfo = new ResourceRevision.Info(revisionList);
       CALWorkspace.SyncTimeInfo syncTimeInfo = new CALWorkspace.SyncTimeInfo(syncTimeList);
      
       return new CALWorkspace.ResourceInfo(resourceRevisionInfo, syncTimeInfo);
      
   }
  

}
TOP

Related Classes of org.openquark.cal.services.WorkspacePersistenceManager

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.