1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.interview;
  28 
  29 import com.sun.javatest.tool.jthelp.HelpID;
  30 import com.sun.javatest.tool.jthelp.HelpSet;
  31 
  32 import java.io.File;
  33 import java.net.MalformedURLException;
  34 import java.net.URL;
  35 import java.net.URLClassLoader;
  36 import java.util.*;
  37 
  38 /**
  39  * Implementation of the HelpSetFactory interface which is aware of javax.help
  40  * library.
  41  *
  42  * @author Dmitry Fazunenko
  43  */
  44 public class JavaHelpFactory implements HelpSetFactory {
  45 
  46     private static final ResourceBundle i18n = ResourceBundle.getBundle("com.sun.interview.i18n");
  47 
  48     public JavaHelpFactory() {
  49     }
  50 
  51     public Object createHelpSetObject(String name, Class<?> c) throws Interview.Fault {
  52         ClassLoader cl = c.getClassLoader();
  53         String hsn;
  54         String pref = "";
  55         if (name.startsWith("/")) {
  56             hsn = name.substring(1); // strip off leading /
  57             pref = hsn.substring(0, hsn.lastIndexOf("/")+1);
  58         } else {
  59             String cn = c.getName();
  60             String pn = cn.substring(0, cn.lastIndexOf('.'));
  61             hsn = pn.replace('.', '/') + "/" + name;
  62             pref = hsn.substring(0, hsn.indexOf(name));
  63         }
  64         URL u = HelpSet.findHelpSet(cl, hsn);
  65         if (u == null) {
  66             throw new HelpNotFoundFault(i18n, "interview.cantFindHelp", hsn);
  67         }
  68         return new HelpSet(cl, u, pref);
  69     }
  70 
  71     public Object createHelpSetObject(String name, File file) throws Interview.Fault {
  72         try {
  73             URL[] urls = {new URL("file:" + file.getAbsolutePath() + "/")};
  74             URLClassLoader cl = new URLClassLoader(urls);
  75             URL url = HelpSet.findHelpSet(cl, name);
  76             if (url == null) {
  77                 throw new HelpNotFoundFault(i18n, "interview.cantFindHelp",
  78                         file.getPath());
  79             }
  80             HelpSet helpset = new HelpSet(cl, url);
  81             return helpset;
  82         } catch (MalformedURLException e) {
  83             throw new HelpNotFoundFault(i18n, "interview.cantFindHelp", file.getPath());
  84         }
  85     }
  86 
  87     public Object createHelpID(Object hsObject, String target) {
  88         if (hsObject != null) {
  89             HelpSet hs = (HelpSet) hsObject;
  90             HashMap<String, URL> m = hs.getCombinedMap();
  91             if (m != null && !m.isEmpty()) {
  92                 return HelpID.create(target, hs);
  93             }
  94         }
  95 
  96         return null;
  97     }
  98 
  99     public Object updateHelpSetObject(Interview interview, Object object) {
 100         HelpSet newHelpSet = (HelpSet)object;
 101         HelpSet oldHelpSet = (HelpSet)interview.getHelpSet();
 102         if (interview.getParent() == null) {
 103             if (oldHelpSet == null) {
 104                 // no previously registered helpset
 105                 // so add in any helpsets for child interviews
 106                 for (Iterator<Interview> iter = interview.getInterviews().iterator(); iter.hasNext(); ) {
 107                     Interview i = iter.next();
 108                     HelpSet ihs = (HelpSet)i.getHelpSet();
 109                     if (ihs != null)
 110                         newHelpSet.add(ihs);
 111                     }
 112                 }
 113             else {
 114                 // reregister child help sets with new help set
 115                List<HelpSet> helpSetsToRemove = new ArrayList<HelpSet>();
 116 
 117                 // transfer help sets old to new
 118                 for (HelpSet entry : oldHelpSet.getHelpSets()) {
 119                     helpSetsToRemove.add(entry);
 120                     newHelpSet.add(entry);
 121                 }   // for
 122 
 123 
 124                 // now remove the sets from the old helpset
 125                 for (Iterator<HelpSet> iterator = helpSetsToRemove.iterator();
 126                                iterator.hasNext();) {
 127                     HelpSet helpToRemove = iterator.next();
 128                     oldHelpSet.remove(helpToRemove);
 129                 }  // for
 130             }
 131         }
 132         else {
 133             Interview i = interview;
 134             while (i.getParent() != null)
 135                 i = i.getParent();
 136             HelpSet rootHelpSet = (HelpSet)i.getHelpSet();
 137             if (rootHelpSet != null) {
 138                 // remove old help set, if any, from root help set
 139                 // ALERT: WHAT IF THE OLD HELPSET WAS REQUIRED BY DIFFERENT
 140                 //        SUBINTERVIEWS -- IN THAT CASE, WE SHOULD NOT REMOVE
 141                 //        IT HERE
 142                 if (oldHelpSet != null)
 143                     rootHelpSet.remove(oldHelpSet);
 144                 // register new helpset with root help set
 145                 rootHelpSet.add(newHelpSet);
 146             }
 147         }
 148 
 149         // finally, update helpset
 150         return newHelpSet;
 151     }
 152 
 153     /**
 154      * This exception is thrown when a named help set cannot be found.
 155      */
 156     public static class HelpNotFoundFault extends Interview.Fault {
 157         HelpNotFoundFault(ResourceBundle i18n, String s, String name) {
 158             super(i18n, s, name);
 159             this.name = name;
 160         }
 161 
 162         /**
 163          * The name of the help set that could not be found.
 164          */
 165         public final String name;
 166     }
 167 
 168     /**
 169      * This exception is to report problems found while opening a JavaHelp help set.
 170      */
 171     public static class BadHelpFault extends Interview.Fault {
 172         BadHelpFault(ResourceBundle i18n, String s, Exception e) {
 173             super(i18n, s, e.getMessage());
 174         }
 175     }
 176 
 177 }