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);
}
}