1 19 20 22 package org.netbeans.nbbuild; 23 24 import java.io.ByteArrayInputStream ; 25 import java.io.File ; 26 import java.net.URI ; 27 import java.net.URL ; 28 import java.util.ArrayList ; 29 import java.util.Collections ; 30 import java.util.Enumeration ; 31 import java.util.HashSet ; 32 import java.util.Hashtable ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Locale ; 36 import java.util.Set ; 37 import javax.help.HelpSet; 38 import javax.help.IndexItem; 39 import javax.help.IndexView; 40 import javax.help.NavigatorView; 41 import javax.help.TOCItem; 42 import javax.help.TOCView; 43 import javax.help.TreeItem; 44 import javax.help.TreeItemFactory; 45 import javax.swing.tree.DefaultMutableTreeNode ; 46 import javax.xml.parsers.SAXParser ; 47 import javax.xml.parsers.SAXParserFactory ; 48 import org.apache.tools.ant.BuildException; 49 import org.apache.tools.ant.FileScanner; 50 import org.apache.tools.ant.Location; 51 import org.apache.tools.ant.Project; 52 import org.apache.tools.ant.Task; 53 import org.apache.tools.ant.types.FileSet; 54 import org.apache.tools.ant.types.Mapper; 55 import org.xml.sax.Attributes ; 56 import org.xml.sax.InputSource ; 57 import org.xml.sax.SAXException ; 58 import org.xml.sax.helpers.DefaultHandler ; 59 60 70 public class CheckHelpSets extends Task { 71 72 private List <FileSet> filesets = new ArrayList <FileSet>(); 73 74 78 public void addFileset(FileSet fs) { 79 filesets.add(fs); 80 } 81 82 public void execute() throws BuildException { 83 Iterator it = filesets.iterator(); 84 while (it.hasNext()) { 85 FileSet fs = (FileSet)it.next(); 86 FileScanner scanner = fs.getDirectoryScanner(getProject()); 87 File dir = scanner.getBasedir(); 88 String [] files = scanner.getIncludedFiles(); 89 for (int i = 0; i < files.length; i++) { 90 File helpset = new File (dir, files[i]); 91 try { 92 checkHelpSet(helpset); 93 } catch (BuildException be) { 94 throw be; 95 } catch (Exception e) { 96 throw new BuildException("Error checking helpset", e, new Location(helpset.getAbsolutePath())); 97 } 98 } 99 } 100 } 101 102 private void checkHelpSet(File hsfile) throws Exception { 103 log("Checking helpset: " + hsfile); 104 HelpSet hs = new HelpSet(null, hsfile.toURI().toURL()); 105 javax.help.Map map = hs.getCombinedMap(); 106 log("Parsed helpset, checking map IDs in TOC/Index navigators..."); 107 NavigatorView[] navs = hs.getNavigatorViews(); 108 for (int i = 0; i < navs.length; i++) { 109 String name = navs[i].getName(); 110 File navfile = new File (hsfile.getParentFile(), (String )navs[i].getParameters().get("data")); 111 if (! navfile.exists()) throw new BuildException("Navigator " + name + " not found", new Location(navfile.getAbsolutePath())); 112 if (navs[i] instanceof IndexView) { 113 log("Checking index navigator " + name, Project.MSG_VERBOSE); 114 IndexView.parse(navfile.toURI().toURL(), hs, Locale.getDefault(), new VerifyTIFactory(hs, map, navfile, false)); 115 } else if (navs[i] instanceof TOCView) { 116 log("Checking TOC navigator " + name, Project.MSG_VERBOSE); 117 TOCView.parse(navfile.toURI().toURL(), hs, Locale.getDefault(), new VerifyTIFactory(hs, map, navfile, true)); 118 } else { 119 log("Skipping non-TOC/Index view: " + name, Project.MSG_VERBOSE); 120 } 121 } 122 log("Checking for duplicate map IDs..."); 123 HelpSet.parse(hsfile.toURI().toURL(), null, new VerifyHSFactory()); 124 log("Checking links from help map and between HTML files..."); 125 Enumeration e = map.getAllIDs(); 126 Set <URI > okurls = new HashSet <URI >(1000); 127 Set <URI > badurls = new HashSet <URI >(1000); 128 Set <URI > cleanurls = new HashSet <URI >(1000); 129 while (e.hasMoreElements()) { 130 javax.help.Map.ID id = (javax.help.Map.ID)e.nextElement(); 131 URL u = map.getURLFromID(id); 132 if (u == null) { 133 throw new BuildException("Bogus map ID: " + id.id, new Location(hsfile.getAbsolutePath())); 134 } 135 log("Checking ID " + id.id, Project.MSG_VERBOSE); 136 CheckLinks.scan(this, id.id, "", new URI (u.toExternalForm()), okurls, badurls, cleanurls, false, false, false, 2, Collections.<Mapper>emptyList()); 137 } 138 } 139 140 private final class VerifyTIFactory implements TreeItemFactory { 141 142 private final HelpSet hs; 143 private final javax.help.Map map; 144 private final File navfile; 145 private final boolean toc; 146 public VerifyTIFactory(HelpSet hs, javax.help.Map map, File navfile, boolean toc) { 147 this.hs = hs; 148 this.map = map; 149 this.navfile = navfile; 150 this.toc = toc; 151 } 152 153 155 public TreeItem createItem(String str, Hashtable hashtable, HelpSet helpSet, Locale locale) { 156 String target = (String )hashtable.get("target"); 157 if (target != null) { 158 if (! map.isValidID(target, hs)) { 159 log(navfile + ": invalid map ID: " + target, Project.MSG_WARN); 160 } else { 161 log("OK map ID: " + target, Project.MSG_VERBOSE); 162 } 163 } 164 return createItem(); 165 } 166 167 169 public Enumeration listMessages() { 170 return Collections.enumeration(Collections.<String >emptyList()); 171 } 172 173 public void processPI(HelpSet helpSet, String str, String str2) { 174 } 175 176 public void reportMessage(String str, boolean param) { 177 log(str, param ? Project.MSG_VERBOSE : Project.MSG_WARN); 178 } 179 180 public void processDOCTYPE(String str, String str1, String str2) { 181 } 182 183 public void parsingStarted(URL uRL) { 184 } 185 186 public DefaultMutableTreeNode parsingEnded(DefaultMutableTreeNode defaultMutableTreeNode) { 187 return defaultMutableTreeNode; 188 } 189 190 public TreeItem createItem() { 191 if (toc) { 192 return new TOCItem(); 193 } else { 194 return new IndexItem(); 195 } 196 } 197 198 } 199 200 private final class VerifyHSFactory extends HelpSet.DefaultHelpSetFactory { 201 202 private Set <String > ids = new HashSet <String >(1000); 203 204 public void processMapRef(HelpSet hs, Hashtable attrs) { 205 try { 206 URL map = new URL (hs.getHelpSetURL(), (String )attrs.get("location")); 207 SAXParserFactory factory = SAXParserFactory.newInstance(); 208 factory.setValidating(false); 209 factory.setNamespaceAware(false); 210 SAXParser parser = factory.newSAXParser(); 211 parser.parse(new InputSource (map.toExternalForm()), new Handler (map.getFile())); 212 } catch (Exception e) { 213 e.printStackTrace(); 214 } 215 } 216 217 private final class Handler extends DefaultHandler { 218 219 private final String map; 220 public Handler(String map) { 221 this.map = map; 222 } 223 224 public void startElement(String uri, String lname, String name, Attributes attributes) throws SAXException { 225 if (name.equals("mapID")) { 226 String target = attributes.getValue("target"); 227 if (target != null) { 228 if (ids.add(target)) { 229 log("Found map ID: " + target, Project.MSG_DEBUG); 230 } else { 231 log(map + ": duplicated ID: " + target, Project.MSG_WARN); 232 } 233 } 234 } 235 } 236 237 public InputSource resolveEntity(String pub, String sys) throws SAXException { 238 if (pub.equals("-//Sun Microsystems Inc.//DTD JavaHelp Map Version 1.0//EN") || 239 pub.equals("-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN")) { 240 return new InputSource (new ByteArrayInputStream (new byte[0])); 242 } else { 243 return null; 244 } 245 } 246 247 } 248 249 } 250 251 } 252 | Popular Tags |