/* * * Copyright 2007-2008 University Of Southern California * * 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 edu.isi.pegasus.planner.catalog.site.impl; import edu.isi.pegasus.common.logging.LogManagerFactory; import edu.isi.pegasus.common.logging.LoggingKeys; import edu.isi.pegasus.planner.catalog.SiteCatalog; import edu.isi.pegasus.planner.catalog.site.SiteCatalogException; import edu.isi.pegasus.planner.catalog.site.classes.SiteCatalogEntry; import edu.isi.pegasus.planner.catalog.site.classes.SiteStore; import edu.isi.pegasus.common.logging.LogManager; import edu.isi.pegasus.common.util.FileUtils; import edu.isi.pegasus.planner.classes.PegasusBag; import edu.isi.pegasus.planner.common.PegasusProperties; import edu.isi.pegasus.planner.parser.SiteCatalogXMLParser; import edu.isi.pegasus.planner.parser.SiteCatalogXMLParserFactory; import edu.isi.pegasus.planner.parser.StackBasedXMLParser; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; /** * An implementation of the Site Catalog interface that is backed up by * an XML file conforming to site catalog xml schema version 3 or version 4 * * The schemas can be found online at * * <pre> * http://pegasus.isi.edu/schema/sc-4.1.xsd * http://pegasus.isi.edu/schema/sc-3.0.xsd * </pre> * * @author Karan Vahi * @version $Revision$ */ public class XML implements SiteCatalog { /** * The default basename of the site catalog file. */ public static final String DEFAULT_SITE_CATALOG_BASENAME = "sites.xml"; /** * The handle to parser instance that will parse the site catalog. */ private SiteCatalogXMLParser mParser; /** * Stores sites in memory */ //private Map<String, SiteCatalogEntry>mSiteMap; private SiteStore mSiteStore; /** * The Site Catalog file to be parser. */ private String mFilename; /** * The handle to the log manager. */ private LogManager mLogger; /** * The bag of Pegasus Initialization objects */ private PegasusBag mBag; /** * The default constructor. */ public XML(){ mLogger = LogManagerFactory.loadSingletonInstance(); mBag = new PegasusBag(); mBag.add( PegasusBag.PEGASUS_LOGMANAGER, mLogger ); mBag.add( PegasusBag.PEGASUS_PROPERTIES, PegasusProperties.nonSingletonInstance() ); //mSiteMap = new HashMap<String,SiteCatalogEntry>(); } /** * Establishes a connection to the file from the properties. * You will need to specify a "file" property to point to the * location of the on-disk instance. * * @param props is the property table with sufficient settings to * to connect to the implementation. * * @return true if connected, false if failed to connect. * * @throws SiteCatalogException */ public boolean connect( Properties props ) throws SiteCatalogException{ if ( props.containsKey("file") ){ return connect( props.getProperty("file") ); } File file = this.getDefaultPathToSC(); if( file.exists() && file.canRead() ){ mLogger.log( "Picking up default site catalog file " + file , LogManager.CONFIG_MESSAGE_LEVEL ); return connect( file.getAbsolutePath() ); } //complain for the property not set throw new SiteCatalogException( "Please specify the property " + SiteCatalog.c_prefix + ".file" + " in your properties file or have the file " + XML.DEFAULT_SITE_CATALOG_BASENAME + " in the current working directory " ); } /** * Initializes the Site Catalog Parser instance for the file. * * @param filename is the name of the file to read. * * @return true, */ public boolean connect( String filename ) throws SiteCatalogException{ mFilename = filename; File f = new File( filename ); if ( f.exists() && f.canRead() ){ return true; } else{ throw new SiteCatalogException( "Cannot read or access file " + filename ); } } /** * Close the connection to backend file. */ public void close() { mFilename = null; } /** * Returns if the connection is closed or not. * * @return boolean */ public boolean isClosed() { return mFilename == null; } /** * Loads up the Site Catalog implementation with the sites whose * site handles are specified. This is a convenience method, that can * allow the backend implementations to maintain soft state if required. * * If the implementation chooses not to implement this, just do an empty * implementation. * * The site handle * is a special handle designating all sites are to be * loaded. * * @param sites the list of sites to be loaded. * * @return the number of sites loaded. * * @throws SiteCatalogException in case of error. */ public int load( List<String> sites ) throws SiteCatalogException { if( this.isClosed() ){ throw new SiteCatalogException( "Need to connect to site catalog before loading" ); } mParser = SiteCatalogXMLParserFactory.loadSiteCatalogXMLParser( this.mBag, mFilename, sites ); mLogger.logEventStart( LoggingKeys.EVENT_PEGASUS_PARSE_SITE_CATALOG , "site-catalog.id", mFilename, LogManager.DEBUG_MESSAGE_LEVEL ); ((StackBasedXMLParser)mParser).startParser( mFilename ); mLogger.logEventCompletion( LogManager.DEBUG_MESSAGE_LEVEL ); mSiteStore = mParser.getSiteStore(); return mSiteStore.list().size(); } /** * Not implemented as yet. * * @param entry * @return number of entries inserted. * @throws edu.isi.pegasus.planner.catalog.site.SiteCatalogException */ public int insert(SiteCatalogEntry entry) throws SiteCatalogException { throw new UnsupportedOperationException("Not supported yet."); } /** * Lists the site handles for all the sites in the Site Catalog. * * @return A set of site handles. * * @throws SiteCatalogException in case of error. */ public Set<String> list() throws SiteCatalogException { return ( mSiteStore == null )? new HashSet(): mSiteStore.list(); } /** * Retrieves the <code>SiteCatalogEntry</code> for a site. * * @param handle the site handle / identifier. * * @return SiteCatalogEntry in case an entry is found , or <code>null</code> * if no match is found. * * * @throws SiteCatalogException in case of error. */ public SiteCatalogEntry lookup(String handle) throws SiteCatalogException { return ( mSiteStore == null )? null: mSiteStore.lookup( handle ); } /** * Not yet implemented as yet. * * @param handle * @return number of entries removed. * @throws edu.isi.pegasus.planner.catalog.site.SiteCatalogException */ public int remove( String handle ) throws SiteCatalogException { throw new UnsupportedOperationException("Not supported yet."); } /** * Returns the File Source for the Site Catalog * * @return path to the backend catalog file , else null */ public File getFileSource( ){ return new File(mFilename); } /** * Copies the source backend to the directory passed. * * For database backends can return null * * @param directory * * @return path to the copied source file, else null. */ public File copy( File directory ){ File copiedFile = null; try { copiedFile = FileUtils.copy( new File( mFilename ), directory); } catch (IOException ex) { mLogger.log( "Unable to copy site catalog file " + mFilename + " to directory " + directory + " " + ex.getMessage(), LogManager.ERROR_MESSAGE_LEVEL ); } return copiedFile; } /** * Returns the default path to the site catalog file. * * @return sites.xml in the current working dir * */ protected File getDefaultPathToSC() { File f = new File( ".", XML.DEFAULT_SITE_CATALOG_BASENAME); //System.err.println("Default Path to SC is " + f.getAbsolutePath()); return f; } }