1
2
3
4
5 package net.sourceforge.jdbdump.connect;
6 import java.io.File;
7 import java.io.IOException;
8 import java.net.JarURLConnection;
9 import java.net.URL;
10 import java.util.ArrayList;
11 import java.util.Enumeration;
12 import java.util.Iterator;
13 import java.util.jar.JarFile;
14 import java.util.zip.ZipEntry;
15 import org.apache.log4j.Logger;
16
17 /***
18 * A DatabaseConnectorFactory is an object that lists all the database types that can be
19 * backed up and creates connectors to the specific database types.
20 * Connectors are the objects that extend the DatabaseConnector class and provide methods that enable
21 * you to create backup of a specific database.
22 * This class implements two design patterns: Factory and Singleton.
23 * Factory pattern makes it easy to produce the proper databse connector.
24 * Singleton pattern checks if there is only one instance of DatabaseConnectorFactory.
25 *
26 * @author tomgur
27 *
28 */
29
30 public class DatabaseConnectorFactory {
31 /***an object providing Singleton desing pattern implementation */
32 public static DatabaseConnectorFactory singleton = null;
33
34 /*** A log4j logger for this class. */
35 private static Logger logger = Logger.getLogger(DatabaseConnectorFactory.class);
36
37
38 /***
39 *
40 * Imlements Singleton desing pattern
41 *
42 */
43 public static DatabaseConnectorFactory getInstance(){
44 if (singleton == null){
45 synchronized(DatabaseConnectorFactory.class){
46 DatabaseConnectorFactory localFactory = new DatabaseConnectorFactory();
47 singleton = localFactory;
48 }
49 }
50
51 return singleton;
52 }
53 /***
54 * Lists all database plugins that are available.
55 * @return a list of available classes extending DatabaseConnector
56 */
57 public String[] listPlugins() {
58 ArrayList<String> plugins = listPlugins("net.sourceforge.jdbdump.connect.connectors",
59 "net.sourceforge.jdbdump.connect.DatabaseConnector");
60 return (String[]) plugins.toArray(new String[0]);
61 }
62
63 /***
64 * Lists all the classes inheriting a given
65 * class in the currently loaded packages.
66 * @param tosubclassname the name of the class to inherit from
67 * @throws ClassNotFoundException
68 */
69 public ArrayList<String> listPlugins(String tosubclassname) {
70 ArrayList<String> pluginsTmp = new ArrayList<String>();
71 ArrayList<String> plugins = new ArrayList<String>();
72 String plugin;
73 try {
74 Class tosubclass = Class.forName(tosubclassname);
75 Package [] pcks = Package.getPackages();
76 for (int i=0;i<pcks.length;i++) {
77
78 pluginsTmp = listPlugins(pcks[i].getName(), tosubclass);
79 if(pluginsTmp != null) {
80 for(Iterator it = pluginsTmp.iterator();it.hasNext();) {
81 plugin = it.next().toString();
82 plugins.add(plugin);
83 }
84 }
85 }
86 }
87 catch (ClassNotFoundException ex) {
88 logger.warn("listPlugins(String tosubclassname): Error while finding class: " + ex);
89 }
90
91 return plugins;
92 }
93
94
95 /***
96 * Listss all the classes inheriting a given
97 * class in a given package.
98 * @param pckgname the fully qualified name of the package
99 * @param tosubclass the name of the class to inherit from
100 * @throws ClassNotFoundException
101 */
102 public ArrayList<String> listPlugins(String pckname, String tosubclassname) {
103 ArrayList<String> plugins = new ArrayList<String>();
104 try {
105 Class tosubclass = Class.forName(tosubclassname);
106 plugins = listPlugins(pckname,tosubclass);
107 }
108 catch (ClassNotFoundException e) {
109 logger.error("listPlugins(String pckname, String tosubclassname): Error while finding class: " + e);
110 }
111
112 return plugins;
113
114 }
115
116
117 /***
118 * Lists all the classes inheriting a given
119 * class in a given package.
120 * @param pckgname the fully qualified name of the package
121 * @param tosubclass the Class object to inherit from
122 * @throws ClassNotFoundException
123 * @throws InstantiationException
124 * @throws IllegalAccessException
125 * @throws IOException
126 */
127 public ArrayList<String> listPlugins(String pckgname, Class tosubclass) {
128
129 ArrayList<String> plugins = new ArrayList<String>();
130 String plugin;
131
132 String name = new String(pckgname);
133 if (!name.startsWith("/")) {
134 name = "/" + name;
135 }
136 name = name.replace('.','/');
137
138
139 URL url = DatabaseConnectorFactory.class.getResource(name);
140
141
142
143 if (url==null) return null;
144
145 File directory = new File(url.getFile());
146
147
148 if (directory.exists()) {
149
150 String [] files = directory.list();
151 for (int i=0;i<files.length;i++) {
152
153
154 if (files[i].endsWith(".class")) {
155
156 String classname = files[i].substring(0,files[i].length()-6);
157 try {
158
159 Object o = Class.forName(pckgname+"."+classname).newInstance();
160 if (tosubclass.isInstance(o)) {
161 plugin = pckgname+"."+classname;
162
163 plugins.add(plugin);
164 }
165 }
166 catch (ClassNotFoundException e) {
167 logger.error("listPlugins(String pckgname, Class tosubclass): Error while finding class: " + e);
168 }
169 catch (InstantiationException e) {
170
171
172
173 logger.error("listPlugins(String pckgname, Class tosubclass): Error while instantiation: " + e);
174 }
175 catch (IllegalAccessException e) {
176
177 logger.error("listPlugins(String pckgname, Class tosubclass): Illegal Access Error: " + e);
178 }
179 }
180 }
181
182 }
183 else {
184 try {
185
186
187 JarURLConnection conn = (JarURLConnection)url.openConnection();
188 String starts = conn.getEntryName();
189 JarFile jfile = conn.getJarFile();
190 Enumeration e = jfile.entries();
191 while (e.hasMoreElements()) {
192 ZipEntry entry = (ZipEntry)e.nextElement();
193 String entryname = entry.getName();
194 if (entryname.startsWith(starts)
195 &&(entryname.lastIndexOf('/')<=starts.length())
196 &&entryname.endsWith(".class"))
197 {
198 String classname = entryname.substring(0,entryname.length()-6);
199 if (classname.startsWith("/"))
200 classname = classname.substring(1);
201 classname = classname.replace('/','.');
202
203 try {
204
205 Object o = Class.forName(classname).newInstance();
206 if (tosubclass.isInstance(o)) {
207
208 plugin = classname.substring(classname.lastIndexOf('.')+1);
209 plugins.add(plugin);
210 }
211 }
212 catch (ClassNotFoundException ex) {
213 logger.error("listPlugins(String pckgname, Class tosubclass): Error while finding class: " + ex);
214 }
215 catch (InstantiationException ex) {
216
217
218
219 logger.error("listPlugins(String pckgname, Class tosubclass): Error while instantiation: " + ex);
220 }
221 catch (IllegalAccessException iaex) {
222
223 logger.error("listPlugins(String pckgname, Class tosubclass): Illegal Access Error: " + e);
224 }
225 }
226 }
227 }
228 catch (IOException e) {
229 logger.error("listPlugins(String pckgname, Class tosubclass): IOExeption: " + e);
230 }
231 }
232
233 return plugins;
234 }
235 /***
236 * Creates connector to the database on the basis of provided data and implements the Factory
237 * design pattern
238 * @param name - name of the database plugin
239 * @throws ClassNotFoundException
240 * @throws InstantiationException
241 * @throws IllegalAccessException
242 */
243 public DatabaseConnector createConnector(String name){
244
245 DatabaseConnector dbConnector = null;
246 Class connectorClass;
247 try{
248 connectorClass = Class.forName(name);
249 dbConnector = (DatabaseConnector)connectorClass.newInstance();
250 }catch(ClassNotFoundException e){
251 logger.error("createConnector(String name): Error while creating connector: " + e);
252 }catch(InstantiationException e){
253 logger.error("createConnector(String name): Error while creating connector: " + e);
254 }catch(IllegalAccessException e){
255 logger.error("createConnector(String name): Error while creating connector: " + e);
256 }
257 return dbConnector;
258 }
259
260 }