/* * [RFC.java] * * Summary: Generate a reference to an RFC (Request For Comment) Internet Standard. * * Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.8 2009-02-06 include go package in ZIP bundle. */ package com.mindprod.htmlmacros.macro; import com.mindprod.common18.EIO; import com.mindprod.csv.CSVReader; import com.mindprod.fastcat.FastCat; import java.io.BufferedReader; import java.io.EOFException; import java.io.File; import java.io.IOException; import java.util.BitSet; import java.util.HashMap; import static com.mindprod.htmlmacros.macro.Global.configuration; import static java.lang.System.*; /** * Generate a reference to an RFC (Request For Comment) Internet Standard. * * @author Roedy Green, Canadian Mind Products * @version 1.8 2009-02-06 include ZIP bundle. * @see com.mindprod.repair.FindObsoleteRFCs * @since 2005-11 */ public final class RFC extends Macro { // declarations /** * largest possible RFC number, get from http://www.faqs.org/rfcs/ */ public static final int MAX_RFC = 8131 + 100 /* growth */; /** * where the missing rfcs are kept. * Use Randy with faqs.org as a backup. * possible sources: * http://rfc822.openrfc.org/ Randy's . lists obsoletes. fixed pitch. 3 formats * http://www.faqs.org/rfcs/rfc822.html fixed pitch. * http://www.ietf.org/rfc/rfc822.txt -- raw ascii text, lists obsoletes. * http://www.rfc-editor.org/rfc/rfc3156.txt * http://www.faqs.org/rfcs/rfc-obsolete.html obsolete RFCS. */ private static final String MISSING_RFCS_CSV = "embellishment/missingrfcs.csv"; /** * where the obsolte rfcs are kept. */ private static final String OBSOLETE_RFCS_CSV = "embellishment/obsoleterfcs.csv"; /** * how to use the macro */ private static final String USAGE = "\nRFC macro needs RFC number 1 .. " + MAX_RFC; /** * list of RFCs missing from orpenrfc.org */ private static final BitSet missingRFCsOnRandy = new BitSet( MAX_RFC + 1 ); /** * look up by rfc to get replacement, null if no replacement. */ private static final HashMap replacements = new HashMap<>( MAX_RFC ); /** * root directory of the local websites */ private static final File root = new File( configuration.getLocalWebrootWithSlashes() ); // /declarations static { try { final BufferedReader br = EIO.getBufferedReader( new File( root, OBSOLETE_RFCS_CSV ), 64 * 1024, EIO.UTF8 ); final CSVReader r = new CSVReader( br, ',', '\"', "#", true /* hide comments */, true /* trim */, true /* trim */, false /* multiline */ ); try { while ( true ) { // obsolete RFC , replacement rfc final short obsolete = r.getShort(); final short replacement = r.getShort(); replacements.put( obsolete, replacement ); r.skipToNextLine(); } } catch ( EOFException e ) { r.close(); } } catch ( IOException e ) { err.println( "unable to read obsoleterfcs.csv file" ); System.exit( 2 ); } } static { try { final BufferedReader br = EIO.getBufferedReader( new File( root, MISSING_RFCS_CSV ), 64 * 1024, EIO.UTF8 ); final CSVReader r = new CSVReader( br, ',', '\"', "#", true /* hide comments */, true /* trim */, true /* trim */, false /* multiline */ ); try { while ( true ) { // missing RFC on Randy final int missing = r.getInt(); missingRFCsOnRandy.set( missing ); r.skipToNextLine(); } } catch ( EOFException e ) { r.close(); } } catch ( IOException e ) { err.println( "unable to read missingrfcs.csv file" ); System.exit( 2 ); } } // methods /** * guts to Generate reference to a RFC document. Document is HTML formatted, handles columns poorly. * * @param rfcNumber RFC rfcNumber as a String * @param obsolete true if this RFC has been replaced or discontinued. * * @return expanded href to view the RFC. */ private static String expandViaFaqs( final int rfcNumber, final boolean obsolete ) { // formatted, but incomplete // generate link of form http://www.faqs.org/rfcs/rfc7279.html return "RFC " + rfcNumber + "" + ( obsolete ? " (obsolete)" : "" ); }// /method /** * Not currently used * guts to Generate reference to a RFC document. * * @param rfcNumber RFC rfcNumber as a String * @param obsolete true if this is an obsolete RFC * * @return expanded href to view the RFC. * @deprecated */ @SuppressWarnings( { "ConstantConditions", "UnusedDeclaration" } ) private static String expandViaIETF( final int rfcNumber, final boolean obsolete ) { // IETF version, ugly, text no cross links return "RFC " + rfcNumber + "" + ( obsolete ? " (obsolete)" : "" ); }// /method /** * guts to Generate reference to a RFC document. * * @param rfcNumber RFC rfcNumber as a String * @param obsolete true if this is an obsolete RFC * * @return expanded href to view the RFC. */ private static String expandViaRandy( final int rfcNumber, final boolean obsolete ) { return "RFC " + rfcNumber + "" + ( obsolete ? " (obsolete)" : "" ); }// /method /** * typical use: * * @param parms RFC# as a string * @param quiet true if want output suppressed. * @param verbose @return expanded macro HTML */ public String expandMacro( String[] parms, final boolean quiet, final boolean verbose ) { if ( !quiet ) { out.print( "R" ); } if ( parms.length != 1 ) { throw new IllegalArgumentException( USAGE ); } final FastCat sb = new FastCat( 10 ); try { short rfcNumber = Short.parseShort( parms[ 0 ] ); if ( !( 1 <= rfcNumber && rfcNumber <= MAX_RFC ) ) { throw new IllegalArgumentException( USAGE ); } // returns false on rfcNumber out past the end. while ( rfcNumber != 0 ) { final Short replacement = replacements.get( rfcNumber ); final boolean obsolete = replacement != null; if ( missingRFCsOnRandy.get( rfcNumber ) ) { sb.append( expandViaFaqs( rfcNumber, obsolete ) ); } else { sb.append( expandViaRandy( rfcNumber, obsolete ) ); // normal } if ( replacement == null ) { rfcNumber = 0; } else { sb.append( " replaced by " ); rfcNumber = replacement; } } } catch ( NumberFormatException e ) { throw new IllegalArgumentException( USAGE ); } return sb.toString(); }// /method // /methods }