001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.util.markup.xhtml; 018 019import java.io.File; 020import java.io.FileFilter; 021import java.io.IOException; 022import java.util.HashMap; 023import java.util.Map; 024 025import javax.xml.parsers.DocumentBuilder; 026import javax.xml.parsers.DocumentBuilderFactory; 027import javax.xml.parsers.ParserConfigurationException; 028 029import org.junit.jupiter.api.Test; 030import org.xml.sax.EntityResolver; 031import org.xml.sax.ErrorHandler; 032import org.xml.sax.InputSource; 033import org.xml.sax.SAXException; 034import org.xml.sax.SAXParseException; 035 036/** 037 * Usable by tests to check that the html markup files are well formed. 038 * 039 * @author akiraly 040 */ 041public class WellFormedXmlTestCase 042{ 043 private DocumentBuilderFactory factory; 044 045 /** 046 * Checks xml well formedness of html markup files under the current working directory. 047 */ 048 @Test 049 public void markupFiles() 050 { 051 factory = DocumentBuilderFactory.newInstance(); 052 factory.setNamespaceAware(true); 053 054 File root = new File("").getAbsoluteFile(); 055 processDirectory(root); 056 } 057 058 private void processDirectory(File dir) 059 { 060 for (File f : dir.listFiles(fileFilter)) 061 { 062 if (f.isDirectory()) 063 { 064 processDirectory(f); 065 } 066 else 067 { 068 processFile(f); 069 } 070 } 071 } 072 073 private void processFile(File file) 074 { 075 DocumentBuilder builder; 076 077 try 078 { 079 builder = factory.newDocumentBuilder(); 080 } 081 catch (ParserConfigurationException e) 082 { 083 throw new RuntimeException("Configuration exception while parsing xml markup.", e); 084 } 085 086 builder.setEntityResolver(entityResolver); 087 builder.setErrorHandler(errorHandler); 088 089 try 090 { 091 builder.parse(file); 092 } 093 catch (SAXException e) 094 { 095 throw new RuntimeException("Parsing xml sax failed, file: " + file, e); 096 } 097 catch (IOException e) 098 { 099 throw new RuntimeException("Parsing xml io failed, file: " + file, e); 100 } 101 } 102 103 private static final FileFilter fileFilter = new FileFilter() 104 { 105 @Override 106 public boolean accept(File pathname) 107 { 108 String path = pathname.getAbsolutePath().replace('\\', '/'); 109 return !path.contains("/src/test/") && !path.contains("/target/") && 110 !"package.html".equals(pathname.getName()) && 111 (pathname.isDirectory() || pathname.getName().endsWith(".html")); 112 } 113 }; 114 115 private static final ErrorHandler errorHandler = new ErrorHandler() 116 { 117 @Override 118 public void warning(SAXParseException exception) throws SAXException 119 { 120 throw exception; 121 } 122 123 @Override 124 public void error(SAXParseException exception) throws SAXException 125 { 126 throw exception; 127 } 128 129 @Override 130 public void fatalError(SAXParseException exception) throws SAXException 131 { 132 throw exception; 133 } 134 135 }; 136 137 private static final EntityResolver entityResolver = new EntityResolver() 138 { 139 private final Map<String, String> systemIdToUri = new HashMap<>(); 140 141 { 142 systemIdToUri.put("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", 143 "xhtml1-transitional.dtd"); 144 systemIdToUri.put("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", 145 "xhtml1-strict.dtd"); 146 147 /* 148 * Cheating: using xhtml dtd-s for html4 files too because the html4 dtd-s are not valid 149 * xml dtd-s. 150 */ 151 systemIdToUri.put("http://www.w3.org/TR/html4/loose.dtd", "xhtml1-transitional.dtd"); 152 systemIdToUri.put("http://www.w3.org/TR/html4/strict.dtd", "xhtml1-strict.dtd"); 153 } 154 155 @Override 156 public InputSource resolveEntity(String publicId, String systemId) { 157 String uri = systemIdToUri.get(systemId); 158 if (uri != null) 159 { 160 return new InputSource(WellFormedXmlTestCase.class.getResource(uri).toString()); 161 } 162 163 return null; 164 } 165 }; 166}