package javacodebook.regex.html; import java.net.URL; public class AbsoluteLinkVisitor implements LinkVisitor { private URL absUrl = null; public AbsoluteLinkVisitor(URL absUrl) { this.absUrl = absUrl; } public String processLink(String tag, String link, boolean href) { try { URL newLink = new URL(absUrl, link); System.out.println(link + " -> " + newLink); link = newLink.toString(); } catch (Exception e) { System.out.println("Konnte nicht bearbeitet werden: " + link); } return link; } } --- Neue Klasse --- package javacodebook.regex.html; import java.util.regex.*; import java.net.*; import java.io.*; /** * Alle Links (Bilder, externe Scripts, Style-Sheets etc.) * einer HTML-Seite herausfinden und durch einen Visitor * bearbeiten lassen. */ public class LinkProcessor { public String execute(String content, LinkVisitor visitor) throws IOException { String resource = "(<[^>]*?(href|src) *?= *?['\"](.*?)['\"].*?>)"; // Inhalt der URL in einen String einlesen StringBuffer newContent = new StringBuffer(); // Alle Links herausfinden und vom Visitor bearbeiten lassen. Pattern pattern = Pattern.compile(resource, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(content); int start = 0; while (matcher.find()) { String tag = matcher.group(1); String link = matcher.group(3); boolean href = matcher.group(2).equalsIgnoreCase("href"); // Der Visitor bearbeitet nun den Link String newLink = visitor.processLink(tag,link,href); // Wenn null zurückgegeben wird, dann nichts tun. if (link == null) continue; // Den neuen Link anhängen. Dazu erst einmal die // Position des Link in der alten HTML-Seite finden int matchStart = matcher.start(3); int matchEnd = matcher.end(3); // Text bis zum Link an die neue HTML-Seite anfügen newContent.append(content.substring(start, matchStart)); // Neuen Link an die neue HTML-Seite anfügen newContent.append(newLink); // Ende des Link als Anfang des neuen Textes deklarieren start = matchEnd; } // Letzten Teil des Textes aus der alten HTML-Seite // in die neue kopieren. newContent.append(content.substring(start)); return newContent.toString(); } } --- Neue Klasse --- package javacodebook.regex.html; import java.net.URL; /** * Das Interface dient dazu, gefundene Links in HTML-Seiten * zu verändern. */ public interface LinkVisitor { /** * Einen Link bearbeiten bzw. verändern * @param tag Der gesamte HTML-Tag, in dem sich der Link befindet * @param link Der Verweis auf eine ext. Resource innerhalb eines Tag * @param href Ist es ein HREF-Link oder ein SRC-Link? * @param returns Den veränderten Link */ public String processLink(String tag, String link, boolean href); } --- Neue Klasse --- package javacodebook.regex.html; import java.net.URL; import java.io.*; public class Starter { public static void main(String []args) throws Exception { URL url = null; File file = null; try { url = new URL(args[0]); file = new File(args[1]); } catch (Exception e) { printUsage(); return; } // Inhalt der URL lesen und Links anpassen. String content = readContent(url); LinkVisitor visitor = new AbsoluteLinkVisitor(url); LinkProcessor proc = new LinkProcessor(); String newContent = proc.execute(content, visitor); // Den neuen Inhalt in die angegebene Datei schreiben FileWriter fw = new FileWriter(file); fw.write(newContent); fw.close(); } /** * Liest den gesamten Inhalt der URL in einen String ein. */ public static String readContent(URL url) throws IOException { StringBuffer buf = new StringBuffer(); BufferedReader in = new BufferedReader( new InputStreamReader( url.openStream())); // Resource wird ausgelesen und in einen StringBuffer // geschrieben String inputLine; while ((inputLine = in.readLine()) != null) { buf.append(inputLine); buf.append("\n"); } in.close(); return buf.toString(); } private static void printUsage() { System.out.println("Aufruf: java javacodebook.regex.html.Starter "); System.exit(0); } }