1 /*
2  * @(#)Merge.java	1.6 06/10/30
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc.  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.  Sun designates this
10  * particular file as subject to the "Classpath" exception as provided
11  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24  * CA 95054 USA or visit www.sun.com if you need additional information or
25  * have any questions.
26  */
27 
28 package javax.help;
29 
30 import java.util.Locale;
31 import javax.swing.tree.TreeNode;
32 import javax.swing.tree.DefaultMutableTreeNode;
33 import java.lang.reflect.Constructor;
34 
35 /**
36  * Common superclass for all merge types
37  *
38  * @author  Richard Gregor
39  * @version	1.6	10/30/06
40  */
41 public abstract class Merge {
42 
43     /**
44      * Slave node
45      */
46     protected DefaultMutableTreeNode slaveTopNode;
47 
48     /**
49      * HelpSet's locale which is used in sorting
50      */
51     protected Locale locale;
52 
53     /**
54      * Constructs Merge for master and slave NavigatorViews
55      *
56      * @param master The master NavigatorView
57      * @param slave The slave NavigatorView
58      */
Merge(NavigatorView master, NavigatorView slave)59     protected Merge(NavigatorView master, NavigatorView slave){
60 
61         try {
62             Class clss = Class.forName("javax.help.TOCView");
63             if (clss.isInstance(slave)) {
64                 this.slaveTopNode = ((TOCView)slave).getDataAsTree();
65 	    }
66             clss = Class.forName("javax.help.IndexView");
67             if (clss.isInstance(slave)) {
68                 this.slaveTopNode = ((IndexView)slave).getDataAsTree();
69 	    }
70         } catch(ClassNotFoundException exp) {
71             System.err.println(exp);
72         }
73 
74         locale = master.getHelpSet().getLocale();
75         if(locale == null)
76             locale = Locale.getDefault();
77     }
78 
79     /**
80      * Processes merge. Changes master node according merge rules using slave node.
81      *
82      * @param node The master node
83      * @return The changed master node
84      */
processMerge(TreeNode node)85     public abstract TreeNode processMerge(TreeNode node);
86 
87     /**
88      * Merge Nodes. Merge two nodes according to the merging rules of the
89      * masterNode. Each Subclass should override this implementation.
90      *
91      * @param master The master node to merge with
92      * @param slave The node to merge into the master
93      */
mergeNodes(TreeNode master, TreeNode slave)94     public static void mergeNodes(TreeNode master, TreeNode slave) {
95 	// Doesn't do anything
96     }
97 
98     /**
99      * Merge Node Children. Merge the children of a node according to the
100      * merging rules of the parent. Each subclass must implement this method
101      *
102      * @param node The parent node from which the children are merged
103      */
mergeNodeChildren(TreeNode node)104     public static void mergeNodeChildren(TreeNode node) {
105 	// Doesn't do anything
106     }
107 
108     /**
109      * Default Merge factory which creates concrete Merge objects
110      */
111     public static class DefaultMergeFactory {
112 
113         /**
114          * Returns suitable Merge object
115          *
116          * @param masterView The master NavigatorView
117          * @param slaveView The slave NavigatorView
118          * @return The Merge object
119          */
getMerge(NavigatorView masterView, NavigatorView slaveView)120         public static Merge getMerge(NavigatorView masterView, NavigatorView slaveView) {
121 
122             Merge mergeObject = null;
123 	    // throw an NPE early
124 	    if (masterView == null || slaveView == null) {
125 		throw new NullPointerException("masterView and/or slaveView are null");
126 
127 	    }
128             String mergeType = masterView.getMergeType();
129 	    HelpSet hs = masterView.getHelpSet();
130             Locale locale = hs.getLocale();
131 	    ClassLoader loader = hs.getLoader();
132 	    Class klass;
133 	    Constructor konstructor;
134 
135 	    if (mergeType != null) {
136 		try {
137 		    Class types[] = { NavigatorView.class,
138 				      NavigatorView.class };
139 		    Object args[] = { masterView, slaveView };
140 		    if (loader == null) {
141 			klass = Class.forName(mergeType);
142 		    } else {
143 			klass = loader.loadClass(mergeType);
144 		    }
145 		    konstructor = klass.getConstructor(types);
146 		    mergeObject = (Merge) konstructor.newInstance(args);
147 		} catch (Exception ex) {
148 		    ex.printStackTrace();
149 		    throw new RuntimeException("Could not create Merge type " +
150 					       mergeType);
151 		}
152 	    } else {
153 		mergeObject = new AppendMerge(masterView, slaveView);
154 	    }
155             return mergeObject;
156         }
157     }
158 }
159