/*
* 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.
*/
/*
* ModuleContainer.
* Created: Feb 21, 2007
* By: Greg McClement
*/
package org.openquark.cal.compiler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import org.openquark.cal.metadata.CALFeatureMetadata;
import org.openquark.cal.services.CALFeatureName;
import org.openquark.cal.services.ResourceManager;
import org.openquark.cal.services.Status;
import org.openquark.util.Pair;
/**
* Objects that implement this class are needed to initialize the SourceMetricsManager. This is
* the only external dependency of the source metrics manager.
*
* @author GMcClement
*/
public abstract class ModuleContainer {
/**
* @return the number of modules in the container.
*/
public abstract int getNModules();
/**
* Returns the module type info at the position specified by the given index.
* @param i the index of the module type info to return.
* @return the specified module type info.
*/
public abstract ModuleTypeInfo getNthModuleTypeInfo(int i);
/**
* Returns the module type info of the module with the given name.
* @param moduleName the name of a module.
* @return the corresponding module type info.
*/
public abstract ModuleTypeInfo getModuleTypeInfo(ModuleName moduleName);
/**
* Returns the source definition of the module with the given name.
* @param moduleName the name of a module.
* @return the corresponding module source definition.
*/
public abstract ModuleSourceDefinition getSourceDefinition(ModuleName moduleName);
public boolean containsModule(ModuleName name){
return getModuleTypeInfo(name) != null;
}
public abstract ResourceManager getResourceManager(ModuleName moduleName, String resourceType);
public abstract boolean saveMetadata(CALFeatureMetadata metadata, Status saveStatus);
public abstract boolean renameFeature(CALFeatureName oldFeatureName, CALFeatureName newFeatureName, Status renameStatus);
/**
* Use to manage updates of the contents of a module.
* @author GMCCLEMENT
*/
public interface ISourceManager{
public boolean isWriteable(ModuleName moduleName);
// may return null for the string if not available
public String getSource(ModuleName moduleName, CompilerMessageLogger messageLogger);
public boolean saveSource(final ModuleName moduleName, final String moduleDefinition, Status saveStatus);
}
// These are optional methods
/**
* Used for more precise changes to the source.
*
* @author Greg McClement
*/
public interface ISourceManager2{
/**
* Check if the saveSource and getOffset members can be used with the given module.
* @return true if the given module can be updated incrementally.
*/
public boolean canUpdateIncrementally(ModuleName moduleName);
/**
* Update the module contents with the given string.
* @return true if the module was successfully updated.
*/
public boolean saveSource(final ModuleName moduleName, final int startIndex, final int endIndex, final String newText);
/**
* @return The offset of the given position in the given module.
*/
public int getOffset(final ModuleName name, final SourcePosition position);
/**
* @param name name of the module
* @param offset the offset into the module
* @return the line and column in the document corresponding to the given offset.
* These are one based. This will return null if the offset is not in range.
*/
public Pair<Integer, Integer> getLineAndColumn(final ModuleName name, final int offset);
/**
* This is used to support undo. All of the operations
* after start up will treated
* as a semantic group.
*/
public void startUpdate(ModuleName moduleName);
/**
* This is used to support undo. All of the operations before this is called
* will be considered to be part of a semantic group.
*/
public void endUpdate(ModuleName moduleName);
}
public abstract ISourceManager getSourceManager(ModuleName moduleName);
/**
* Return the source model for the given module name
* @param moduleName the name of the module.
* @param ignoreErrors return the source model even if there are parse errors.
* @return the source model for the given module. Maybe be null if the file is unparsable.
*/
public SourceModel.ModuleDefn getSourceModel(ModuleName moduleName, boolean ignoreErrors, CompilerMessageLogger logger){
String moduleSource = getModuleSource(moduleName);
if (moduleSource.length() == 0){
return null;
}
return SourceModelUtilities.TextParsing.parseModuleDefnIntoSourceModel(moduleSource, ignoreErrors, logger);
}
public String getModuleSource(ModuleName moduleName){
return ModuleContainer.readModuleSource(getSourceDefinition(moduleName));
}
public ModuleName[] getModuleNames(){
final int nModules = getNModules();
ModuleName[] moduleNames = new ModuleName[nModules];
for(int i = 0; i < nModules; ++i){
moduleNames[i] = getNthModuleTypeInfo(i).getModuleName();
}
return moduleNames;
}
/**
* @param moduleSourceDefn The source definition to read the source text for
* @return The source text of a module as a single String
*/
public static String readModuleSource(ModuleSourceDefinition moduleSourceDefn) {
Reader reader = moduleSourceDefn.getSourceReader(new org.openquark.cal.services.Status("reading module source"));
if (reader == null) {
System.err.println("Failed to read module " + moduleSourceDefn.getModuleName());
return null;
}
BufferedReader bufferedReader = new BufferedReader(reader);
try {
StringBuilder stringBuf = new StringBuilder();
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuf.append(line).append('\n');
}
} catch (IOException e) {
System.err.println("Failed to read module " + moduleSourceDefn.getModuleName());
return null;
}
return stringBuf.toString();
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
}