/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* compare page generator */ package netscape.npasw; import netscape.npasw.*; import java.io.*; import java.net.*; import java.lang.*; import java.util.*; import netscape.security.*; //import Trace; public class CPGenerator { public static final int IDLE = 1; public static final int DOWNLOADING = 2; public static final int UNJARRING = 3; public static final int SENDING = 4; public static final int RECEIVING_RESPONSE = 5; public static final int WAITING = 6; public static final int CONTACTING_SERVER = 7; public static final int DONE = 0; public static final int ABORT = -1; public static final String FEATURE_STRING = "FEATURES"; public static final int FEATURE_COUNT = 8; public static final boolean DEBUG = true; public static boolean done = false; public static String currentFile = ""; public static int totalBytes = 0; static final String REG_SOURCE_STRING = "REG_SOURCE"; static int state = DONE; static String regSource; static String ispDirectorySymbol = "isp_dir"; static String comparePageTemplateFileName = "compare.tmpl"; static String comparePageFileName = "compare.htm"; static String localPath; // ispList is a vector of ISPDynamicData's that is created from the stream passed back // from the registration server "POST" static Vector ispList = null; static Vector nameValueSets = null; //static CPGeneratorProgress progress = null; // static final String regservMimeData = "http://seaspace.netscape.com:8080/programs/ias5/regserv/docs/reg.cgi"; public static int getState() { return state; } private static String getLocalPath() { return localPath; } private static String getMetadataPath() { return ( getLocalPath() + "metadata" + File.separator + "html" + File.separator ); } private static String getISPPath() { return ( getLocalPath() + "isp" + File.separator ); } private static String getJarFilePath( ISPDynamicData isp ) { return new String( getISPPath() + isp.getLanguage() + File.separator + isp.getName() + File.separator + isp.getName() + ".jar" ); } private static String getConfigPath( ISPDynamicData isp ) { return new String( getISPPath() + isp.getLanguage() + File.separator + isp.getName() + File.separator + "client_data" + File.separator + "config" + File.separator ); } private static String getConfigFilePath( ISPDynamicData isp ) { return new String( getConfigPath( isp ) + "config.ias" ); } private static String getCompareFilePath( ISPDynamicData isp ) { return new String( getConfigPath( isp ) + "compare.cfg" ); } private static String getMasterFilePath( ISPDynamicData isp ) { return new String( getConfigPath( isp ) + "master.cfg" ); } private static ISPDynamicData getISPDynamicData( String ispName ) { //Trace.TRACE( "getISPDynamicData: " + ispName ); for ( int i = 0; i < ispList.size(); i++ ) { ISPDynamicData ispData = (ISPDynamicData)ispList.elementAt( i ); String name = ispData.getName(); if ( name.compareTo( ispName ) == 0 ) return ispData; } return null; } private static NameValueSet getISPData( String ispName ) { //Trace.TRACE( "getISPData: " + ispName ); for ( int i = 0; i < nameValueSets.size(); i++ ) { NameValueSet nvSet = (NameValueSet)nameValueSets.elementAt( i ); //nvSet.printNameValueSet(); String name = nvSet.getValue( "ISPName" ); if ( name.compareTo( ispName ) == 0 ) return nvSet; } return null; } public static String[] getISPPopList( String isp ) { String retArray[] = null; //Trace.TRACE( "getISPPopList" ); try { ISPDynamicData ispData = getISPDynamicData( isp ); if ( ispData == null ) { //Trace.TRACE( "isp not found: " + isp ); return null; } int size = ispData.getDynamicDataSize(); //Trace.TRACE( "size: " + size ); retArray = new String[ size ]; while ( size > 0 ) { size = size - 1; NameValueSet nvSet = ispData.getDynamicData( size ); String phoneNum = nvSet.getValue( "phone" ); String city = nvSet.getValue( "city" ); String state = nvSet.getValue( "state" ); String entry = phoneNum + ", " + city + ", " + state; retArray[ size ] = entry; //Trace.TRACE( "entry: " + entry ); } } catch ( Throwable e ) { retArray = null; e.printStackTrace(); } return retArray; } public static void createConfigIAS( String ispName, int index ) { // * fill in the variables in each "config.ias" with the dynamic data from the server ISPDynamicData ispData = getISPDynamicData( ispName ); String inputFileName = getConfigFilePath( ispData ); String outputFileName = inputFileName + ".r"; //Trace.TRACE( "inputFileName: " + inputFileName ); //Trace.TRACE( "outputFileName: " + outputFileName ); File inputFile = new File( inputFileName ); File outputFile = new File( outputFileName ); try { NameValueSet nvSet = ispData.getDynamicData( index ); if ( nvSet == null ) nvSet = new NameValueSet(); executeNameValueReplacement( ispData.getDynamicData( index ), inputFile, outputFile ); } catch ( Throwable e ) { e.printStackTrace(); } //if ( inputFile.delete() ) //{ // Trace.TRACE( "deleted ISP config file" ); // if ( outputFile.renameTo( inputFile ) ) // ; //Trace.TRACE( "rename succeeded" ); //} } public static String getISPDisplayName( String ispName ) { NameValueSet nvSet = getISPData( ispName ); if ( nvSet != null ) { //Trace.TRACE( "have nvSet" ); String ispDisplayName = new String ( nvSet.getValue( "DisplayName" ) ); //Trace.TRACE( "ispDisplayName: " + ispDisplayName ); return ispDisplayName; } return null; } /* Takes the given inputFile and looks for strings in the form "@@@string_to_replace@@@" and replaces them with the value found in nvSet, writing the output into outputFile @return void @param nvSet NameValueSet that contains the name/value pairs to use for replacement @param inputFile file containing replacement strings in the form "@@@string_to_replace@@@" @param outputFile file that is created */ public static void executeNameValueReplacement( NameValueSet nvSet, File inputFile, File outputFile ) throws Exception { if ( outputFile.exists() ) { //Trace.TRACE( "deleting outputfile: " + outputFile.getPath() ); outputFile.delete(); } BufferedReader bufferedInputReader = new BufferedReader( new FileReader( inputFile ) ); BufferedWriter bufferedOutputWriter = new BufferedWriter( new FileWriter( outputFile ) ); int c = bufferedInputReader.read(); while ( c != -1 ) { if ( c == '@' ) { bufferedInputReader.mark( 1024 ); boolean successful = false; int c1; int c2 = -1; c1 = bufferedInputReader.read(); if ( c1 != -1 ) c2 = bufferedInputReader.read(); if ( c1 == '@' && c2 == '@' ) { StringBuffer buffer = new StringBuffer( 256 ); int c3 = bufferedInputReader.read(); while ( c3 != -1 && c3 != '@' ) { buffer.append( (char)c3 ); c3 = bufferedInputReader.read(); } //Trace.TRACE( "read identifier: " + buffer.toString() ); if ( c3 == '@' ) { c2 = -1; c1 = bufferedInputReader.read(); if ( c1 != -1 ) c2 = bufferedInputReader.read(); if ( c1 == '@' && c2 == '@' ) { //Trace.TRACE( "successful" ); successful = true; String name = new String( buffer ); //Trace.TRACE( "grepping nvSet for " + name ); //nvSet.printNameValueSet(); String value; if ( nvSet == null ) value = new String( "" ); else { value = nvSet.getValue( name ); if ( value == null ) value = new String( "" ); } //Trace.TRACE( "value is: " + value ); bufferedOutputWriter.write( value ); } } } if ( !successful ) { //Trace.TRACE( "not successful, backing up stream" ); bufferedOutputWriter.write( c ); bufferedInputReader.reset(); } } else { bufferedOutputWriter.write( c ); } c = bufferedInputReader.read(); } bufferedOutputWriter.flush(); bufferedOutputWriter.close(); bufferedInputReader.close(); } /* Takes the bufferedInputReader and reads the stream looking for instances of ###filename_minus_extension###, then it will open "filename_minus_extension" + .mat and parse the contents of that file as a NameValueSet. Then, it looks at each NameValueSet in the Vector nvSets and if a given set in that vector is a superset of the .mat NameValueSet, a match is found, the file "filename_minus_extension" + .tmpl is opened and executeNameValueReplacement is called to create a file to be included in the bufferedOutputWriter (got that?) @return void @param bufferedInputReader input file containing constraint template to be replaced @param bufferedOutputWriter output file (html) */ public static void executeConstraintReplacement( Vector inSets, BufferedReader bufferedInputReader, BufferedWriter bufferedOutputWriter ) throws Exception { int c = bufferedInputReader.read(); while ( c != -1 ) { if ( c == '#' ) { bufferedInputReader.mark( 1024 ); boolean successful = false; int c1; int c2 = -1; c1 = bufferedInputReader.read(); if ( c1 != -1 ) c2 = bufferedInputReader.read(); if ( c1 == '#' && c2 == '#' ) { StringBuffer buffer = new StringBuffer( 128 ); int c3 = bufferedInputReader.read(); while ( c3 != -1 && c3 != '#' ) { buffer.append( (char)c3 ); c3 = bufferedInputReader.read(); } if ( c3 == '#' ) { c2 = -1; c1 = bufferedInputReader.read(); if ( c1 != -1 ) c2 = bufferedInputReader.read(); if ( c1 == '#' && c2 == '#' ) { successful = true; String criterionFileName = getMetadataPath() + buffer.toString() + ".mat"; /* will be something like "template1.mat" */ String templateFileName = getMetadataPath() + buffer.toString() + ".tmpl"; /* will be something like "template1.tmpl" */ String outputFileName = getMetadataPath() + buffer.toString() + ".html"; //Trace.TRACE( "criterionFile: " + criterionFileName ); //Trace.TRACE( "templateFile: " + templateFileName ); //Trace.TRACE( "outputFile: " + outputFileName ); File templateFile = new File( templateFileName ); File criterionFile = new File( criterionFileName ); File outputFile = new File( outputFileName ); NameValueSet criterionSet = new NameValueSet( criterionFile ); criterionSet.printNameValueSet(); for ( int i = 0; i < inSets.size(); i++ ) { NameValueSet nvSet = (NameValueSet)inSets.elementAt( i ); //Trace.TRACE( "testing a set: " ); //nvSet.printNameValueSet(); if ( criterionSet.isSubsetOf( nvSet ) ) { executeNameValueReplacement( nvSet, templateFile, outputFile ); BufferedReader bufSubInputReader = new BufferedReader( new FileReader( outputFile ) ); executeConstraintReplacement( inSets, bufSubInputReader, bufferedOutputWriter ); bufSubInputReader.close(); } } } } } if ( !successful ) { bufferedOutputWriter.write( c ); bufferedInputReader.reset(); } } else { bufferedOutputWriter.write( c ); } c = bufferedInputReader.read(); } bufferedOutputWriter.flush(); } /* Opens a connection to "sURL" and sends a POST with the data contained in "reggieData". Each entry in "reggieData" should be a string of the form "name=value". The result send back from the server is then parsed into individual ISPDynamicData's which are put into a Vector and returned @return Vector of ISPDynamicData's @param sURL URL of the server to send the POST to @param reggieData String array with entries of the form "name=value" to send to server as POST */ private static Vector parseMimeStream( String sURL, String reggieData[] ) throws Exception { int nBuffSize = 0; int count = 0; URLConnection urlSrcConn = null; URL urlSrc = null; Vector ispList = new Vector(); ISPDynamicData newData = null; state = CONTACTING_SERVER; //Trace.TRACE( "opening connection to registration server" ); urlSrc = new URL( sURL ); urlSrcConn = urlSrc.openConnection(); state = SENDING; urlSrcConn.setDoOutput( true ); urlSrcConn.setUseCaches( false ); urlSrcConn.setAllowUserInteraction( true ); Trace.TRACE( "sending POST to:" ); Trace.TRACE( sURL ); // * send the post PrintWriter out = new PrintWriter( urlSrcConn.getOutputStream() ); String traceOut = new String(); for ( count = 0; count < reggieData.length; count++ ) { if ( count > 0 ) { out.print( "&" ); traceOut = traceOut + "&"; } out.print( reggieData[ count ] ); traceOut = traceOut + reggieData[ count ]; } out.println(); out.close(); Trace.TRACE( traceOut ); state = WAITING; try { String buffer; InputStream origStream = urlSrcConn.getInputStream(); //Trace.TRACE( "creating reggie stream" ); ReggieStream is = new ReggieStream( origStream ); state = RECEIVING_RESPONSE; buffer = is.nextToken(); if ( buffer.compareTo( "STATUS" ) != 0 ) throw new MalformedReggieStreamException( "no STATUS message sent" ); buffer = is.nextToken(); if ( buffer.compareTo( "OK" ) != 0 ) throw new MalformedReggieStreamException( "STATUS not OK" ); Trace.TRACE( "STATUS=OK" ); buffer = is.nextToken(); if ( buffer.compareTo( "SIZE" ) != 0 ) throw new MalformedReggieStreamException( "no SIZE value sent" ); totalBytes = new Integer( is.nextToken() ).intValue(); Trace.TRACE( "SIZE=" + totalBytes ); buffer = is.nextToken(); if ( buffer.compareTo( REG_SOURCE_STRING ) != 0 ) throw new MalformedReggieStreamException( "no REG_SOURCE value present" ); buffer = is.nextToken(); regSource = buffer; Trace.TRACE( "REG_SOURCE=" + regSource ); while ( true ) { //Trace.TRACE( "trying to create a new ISPDynamicData" ); newData = new ISPDynamicData(); newData.read( is ); //newData.printISPDynamicData(); ispList.addElement( newData ); } } catch ( EOFException e ) { state = DONE; ispList.addElement( newData ); Trace.TRACE( "successfully finished downloading dynamic data" ); } catch ( IOException e ) { state = ABORT; Trace.TRACE( "I/O exception (check the RegCGI URL in the .IAS file)" ); ispList = null; } catch ( MalformedReggieStreamException e ) { state = ABORT; Trace.TRACE( "malformed stream, saving partial dynamic data" ); } //Trace.TRACE( "returning ispList" ); return ispList; } public static void main( String[] arg ) { // generateComparePage( "https://reggie.netscape.com/IAS5/docs/reg.cgi", // new String[] { "CST__PHONE_NUMBER=6743552", "CLIENT_LANGUAGE=en", // "REG_SOURCE=APL", "CST_AREA_CODE_1=415", "CST_AREA_CODE_2=650", // "CST_AREA_CODE_3=408" } ); } private static void parseFeatureSet( NameValueSet ispSet, NameValueSet featureMapping ) { String featureList = ispSet.getValue( FEATURE_STRING ); //Trace.TRACE( "features: " + featureList ); for ( int i = 1; i <= FEATURE_COUNT; i++ ) { String featureName = "feature" + i; String featureMappedName = featureMapping.getValue( featureName ); //Trace.TRACE( featureName + " mapped to " + featureMappedName ); // * featureMappedName will be something like "hosting" or "freetime" if ( featureMappedName != null && featureList != null && featureMappedName.compareTo( "" ) != 0 && featureList.indexOf( featureMappedName ) != -1 ) { //Trace.TRACE( "going to show" ); ispSet.setValue( featureName, "SHOW" ); } else { //Trace.TRACE( "going to hide" ); ispSet.setValue( featureName, "HIDE" ); } } } private static void downloadAndUnzipMetadata( String rootURL ) throws Throwable { state = DOWNLOADING; String zipFileURL = rootURL + "metadata.jar"; String localFileName = getLocalPath() + "metadata.jar"; ServerDownload.downloadURL( zipFileURL, localFileName ); ServerDownload.unJarFile( localFileName, true ); } private static void downloadJarFiles( Vector ispList, String rootURL ) throws Throwable { state = DOWNLOADING; // * download the ".jar" for each ISP for ( int i = 0; i < ispList.size(); i++ ) { ISPDynamicData ispData; ispData = (ISPDynamicData)ispList.elementAt( i ); String zipFileURL = rootURL + "ISP/" + ispData.getLanguage() + "/" + ispData.getName() + "/" + "server_data/" + ispData.getName() + ".jar"; String ispLocalFileName = getJarFilePath( ispData ); currentFile = new String( ispData.getName() ); Trace.TRACE( "downloading: " + zipFileURL ); ServerDownload.downloadURL( zipFileURL, ispLocalFileName ); } } private static void decompressJarFiles( Vector ispList ) throws Throwable { state = UNJARRING; // * decompress the ".jar" for each ISP for ( int i = 0; i < ispList.size(); i++ ) { ISPDynamicData ispData; ispData = (ISPDynamicData)ispList.elementAt( i ); String ispLocalFileName = getJarFilePath( ispData ); currentFile = new String( ispLocalFileName ); Trace.TRACE( "unzipping: " + ispLocalFileName ); ServerDownload.unJarFile( ispLocalFileName, true ); } } private static Vector parseCompareFiles( Vector ispList, NameValueSet featureMappings ) throws Throwable { // * create a name/value set for each ISP by parsing the "compare.cfg" files Vector returnSets = new Vector(); for ( int i = 0; i < ispList.size(); i++ ) { ISPDynamicData ispData; ispData = (ISPDynamicData)ispList.elementAt( i ); String ispConfigFileName = getCompareFilePath( ispData ); String ispMasterFileName = getMasterFilePath( ispData ); //Trace.TRACE( "ispConfigFileName: " + ispConfigFileName ); File ispConfigFile = new File( ispConfigFileName ); File ispMasterFile = new File( ispMasterFileName ); NameValueSet nvSet = new NameValueSet(); nvSet.setIgnoreSections( true ); if ( ispConfigFile.exists() ) nvSet.read( ispConfigFile ); if ( ispMasterFile.exists() ) nvSet.read( ispMasterFile ); nvSet.setValue( ispDirectorySymbol, new String( ispData.language + "/" + ispData.name + "/client_data" ) ); parseFeatureSet( nvSet, featureMappings ); returnSets.addElement( nvSet ); //nvSet.printNameValueSet(); } return returnSets; } public static boolean generateComparePage( String inLocalPath, String sCGIUrl, String sRootURL, String metadataMode, String reggieData[] ) { done = false; state = IDLE; Trace.TRACE( "Hello" ); NameValueSet featureMappings = null; boolean result = false; localPath = new String( inLocalPath ); ServerDownload.resetBytesDownloaded(); ServerDownload.resetBytesUnjarred(); try { //if ( progress == null ) // progress = new CPGeneratorProgress(); //progress.show(); //progress.toFront(); //new Thread( progress ).start(); // * send "POST" to registration server and parse the returned MIME stream ispList = parseMimeStream( sCGIUrl, reggieData ); if ( metadataMode.toLowerCase().compareTo( "no" ) != 0 ) downloadAndUnzipMetadata( sRootURL ); downloadJarFiles( ispList, sRootURL ); decompressJarFiles( ispList ); //Trace.TRACE( "features.cfg settings: " ); String featuresConfigPath = getLocalPath() + "metadata" + File.separator + "config" + File.separator + "features.cfg"; featureMappings = new NameValueSet( new File( featuresConfigPath ) ); nameValueSets = parseCompareFiles( ispList, featureMappings ); //featureMappings.printNameValueSet(); // * parse the feature list for each ISP //for ( int i = 0; i < dynamicData.size(); i++ ) //{ // ISPDynamicData ispData; // ispData = (ISPDynamicData)dynamicData.elementAt( i ); // // ispData.parseFeatureSet( featureMappings ); // ispData.printISPDynamicData(); // } // * now, generate the compare page using the compare page template and the name/value pairs for each ISP File inputFile = new File( getMetadataPath() + comparePageTemplateFileName ); File outputFile = new File( getLocalPath() + comparePageFileName ); BufferedReader bufferedReader = new BufferedReader( new FileReader( inputFile ) ); BufferedWriter bufferedWriter = new BufferedWriter( new FileWriter( outputFile ) ); executeConstraintReplacement( nameValueSets, bufferedReader, bufferedWriter ); bufferedWriter.close(); bufferedReader.close(); done = true; Thread.yield(); result = true; state = IDLE; //System.in.read(); // prevent console window from going away } catch ( MalformedURLException e ) { Trace.TRACE( e.getMessage() ); e.printStackTrace(); } catch ( ConnectException e ) { Trace.TRACE( e.getMessage() ); e.printStackTrace(); } catch ( UnknownHostException e ) { Trace.TRACE( e.getMessage() ); e.printStackTrace(); } catch ( FileNotFoundException e ) { Trace.TRACE( e.getMessage() ); e.printStackTrace(); } catch ( Exception e ) { Trace.TRACE( e.getMessage() ); e.printStackTrace(); } catch ( Throwable e ) { Trace.TRACE( "caught an exception" ); Trace.TRACE( e.getMessage() ); e.printStackTrace(); } finally { done = true; state = IDLE; } Trace.TRACE( "returning result: " + result ); done = false; return result; } }