001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Library License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: AdminClient.java,v 1.2 2002/06/08 00:49:39 mediumnet Exp $
008:
009: package org.ozoneDB.core.admin;
010:
011: import java.util.Vector;
012: import java.util.zip.*;
013: import java.io.*;
014:
015: import org.w3c.dom.Document;
016: import org.w3c.dom.Node;
017: import org.w3c.dom.NodeList;
018:
019: import javax.xml.parsers.*;
020: import org.xml.sax.helpers.*;
021: import org.xml.sax.*;
022:
023: import org.ozoneDB.DxLib.*;
024: import org.ozoneDB.ExternalDatabase;
025: import org.ozoneDB.ExternalTransaction;
026: import org.ozoneDB.core.admin.Admin;
027: import org.ozoneDB.core.UserManagerExc;
028: import org.ozoneDB.core.User;
029: import org.ozoneDB.core.Group;
030:
031: import org.ozoneDB.xml.util.*;
032: import org.infozone.tools.xml.queries.*;
033:
034: import org.apache.xml.serialize.*;
035:
036: /**
037: * @version $Revision: 1.2 $ $Date: 2002/06/08 00:49:39 $
038: * @author <a href="http://www.smb-tec.com">SMB</a>
039: * @author <a href="http://www.medium.net/">Medium.net</a>
040: */
041: public class AdminClient implements SAXChunkProducerDelegate {
042:
043: final static String COMMAND_NU = "newuser";
044: final static String COMMAND_RU = "removeuser";
045: final static String COMMAND_AU = "allusers";
046: final static String COMMAND_NG = "newgroup";
047: final static String COMMAND_RG = "removegroup";
048: final static String COMMAND_AG = "allgroups";
049: final static String COMMAND_U2G = "user2group";
050: final static String COMMAND_SD = "shutdown";
051: final static String COMMAND_TXS = "txs";
052: final static String COMMAND_BACKUP = "backup";
053: final static String COMMAND_RESTORE = "restore";
054: final static String COMMAND_START_GARBAGECOLLECTION = "startGC";
055:
056: final static String DB_URL = "ozonedb:remote://localhost:3333";
057:
058: String dbURL = DB_URL;
059:
060: PrintWriter out;
061:
062: PrintWriter verboseOut;
063:
064: ExternalDatabase db;
065:
066: Admin admin;
067:
068: public static void main(String[] args) throws Exception {
069: if (args.length == 0 || args[0].equals("-h")
070: || args[0].equals("-help")) {
071: printUsage();
072: System.exit(1);
073: }
074: String command = args[0];
075:
076: AdminClient client = new AdminClient(args);
077:
078: try {
079: client.open();
080:
081: if (command.equals(COMMAND_NU)) {
082: client.newUser(args);
083: } else if (command.equals(COMMAND_AU)) {
084: client.allUsers(args);
085: } else if (command.equals(COMMAND_RU)) {
086: client.removeUser(args);
087: } else if (command.equals(COMMAND_NG)) {
088: client.newGroup(args);
089: } else if (command.equals(COMMAND_AG)) {
090: client.allGroups(args);
091: } else if (command.equals(COMMAND_RG)) {
092: client.removeGroup(args);
093: } else if (command.equals(COMMAND_U2G)) {
094: client.addUser2Group(args);
095: } else if (command.equals(COMMAND_TXS)) {
096: client.numberOfTxs();
097: } else if (command.equals(COMMAND_SD)) {
098: client.shutdown();
099: } else if (command.equals(COMMAND_BACKUP)) {
100: client.backup(args);
101: } else if (command.equals(COMMAND_RESTORE)) {
102: client.restore(args);
103: } else if (command.equals(COMMAND_START_GARBAGECOLLECTION)) {
104: client.startGarbageCollection();
105: } else {
106: System.out.println("Unknown command: " + command);
107: printUsage();
108: }
109: } catch (Exception e) {
110: client.out.println("Error: " + e.getMessage());
111: e.printStackTrace(client.verboseOut);
112: }
113: client.close();
114: }
115:
116: // note that on windows systems the equal (=) gets removed and breaks
117: // the command line into too many arguments
118: // as a work around, the -name=value in double quotes like
119: // "-name=value" allows both Windows and UNIX to work correctly
120: public static void printUsage() {
121: System.out.println("usage: ozoneAdmin <command> [options]");
122: System.out.println("");
123: System.out.println("commands: " + COMMAND_NU + " " + COMMAND_RU
124: + " " + COMMAND_AU + " " + COMMAND_NG + " "
125: + COMMAND_RG + " " + COMMAND_AG + " " + COMMAND_TXS
126: + " " + COMMAND_BACKUP + " " + COMMAND_RESTORE + " "
127: + COMMAND_START_GARBAGECOLLECTION);
128: System.out.println("");
129: System.out
130: .println("note: all -name=value must be within double quotes for Windows systems!");
131: System.out.println("");
132: System.out.println("overall options:");
133: System.out
134: .println(" \"-dburl=<URL>\" The URL of the database. (default: "
135: + DB_URL + ")");
136: System.out
137: .println(" \"-verbose\" Be verbose.");
138: System.out.println("");
139: System.out.println(COMMAND_NU + " options:");
140: System.out.println(" \"-name=<username>\"");
141: System.out.println(" \"-id=<userid>\"");
142: System.out.println("");
143: System.out.println(COMMAND_RU + " options:");
144: System.out.println(" \"-name=<username>\"");
145: System.out.println("");
146: System.out.println(COMMAND_AU + " options:");
147: System.out.println(" -");
148: System.out.println("");
149: System.out.println(COMMAND_NG + " options:");
150: System.out.println(" \"-name=<groupname>\"");
151: System.out.println(" \"-id=<groupid>\"");
152: System.out.println("");
153: System.out.println(COMMAND_RG + " options:");
154: System.out.println(" \"-name=<groupname>\"");
155: System.out.println("");
156: System.out.println(COMMAND_AG + " options:");
157: System.out.println(" -");
158: System.out.println("");
159: System.out.println(COMMAND_U2G + " options:");
160: System.out.println(" \"-username=<username>\"");
161: System.out.println(" \"-groupname=<groupname>\"");
162: System.out.println("");
163: System.out.println(COMMAND_TXS + " options:");
164: System.out.println(" -");
165: System.out.println("");
166: System.out.println(COMMAND_SD + " options:");
167: System.out.println(" -");
168: System.out.println("");
169: System.out.println(COMMAND_BACKUP + " options:");
170: System.out
171: .println(" \"-outfile=<filename>\" The name of the output file. (default: System.out)");
172: System.out
173: .println(" \"-compress\" gzip the output.");
174: System.out
175: .println(" \"-indent\" Indent the XML output.");
176: // System.out.println( " \"-raw\" Write compiled XML." );
177: System.out.println("");
178: System.out.println(COMMAND_RESTORE + " options:");
179: System.out
180: .println(" \"-infile=<filename>\" The name of the input file. (default: System.in)");
181: System.out
182: .println(" \"-compress\" Input is gzipped.");
183: System.out.println("");
184: System.out.println(COMMAND_START_GARBAGECOLLECTION
185: + ": initiate persistent object garbage collection.");
186: }
187:
188: public AdminClient(String[] _args) throws Exception {
189: // use System.out for normal output and skip verbose output
190: out = new PrintWriter(System.out, true);
191: verboseOut = new PrintWriter(new CharArrayWriter());
192:
193: // check command line arguments
194: for (int i = 1; i < _args.length; i++) {
195: String arg = _args[i];
196:
197: if (arg.startsWith("-dburl=")) {
198: dbURL = arg.substring(7);
199: verboseOut.println("dbURL: " + dbURL);
200: } else if (arg.equals("-v") || arg.equals("-verbose")) {
201: verboseOut = new PrintWriter(System.out, true);
202: verboseOut.println("verbose=true");
203: }
204: }
205: }
206:
207: public synchronized void open() throws Exception {
208: db = ExternalDatabase.openDatabase(dbURL);
209: db.reloadClasses();
210:
211: admin = db.admin();
212: }
213:
214: protected synchronized void close() throws Exception {
215: if (db != null) {
216: db.close();
217: db = null;
218: }
219: }
220:
221: protected void newUser(String[] _args) throws Exception {
222: String name = null;
223: int id = -1;
224:
225: // check command line arguments
226: for (int i = 1; i < _args.length; i++) {
227: String arg = _args[i];
228:
229: if (arg.startsWith("-name=")) {
230: name = arg.substring(6);
231: verboseOut.println("name=" + name);
232: } else if (arg.startsWith("-id=")) {
233: id = Integer.parseInt(arg.substring(4));
234: verboseOut.println("id=" + id);
235: } else {
236: out.println("Unknow argument: " + arg);
237: }
238: }
239: try {
240: admin.newUser(name, id);
241: } catch (UserManagerExc e) {
242: out.println("Unable to create new user: " + e.getMessage());
243: }
244: }
245:
246: protected void removeUser(String[] _args) throws Exception {
247: String name = null;
248:
249: // check command line arguments
250: for (int i = 1; i < _args.length; i++) {
251: String arg = _args[i];
252:
253: if (arg.startsWith("-name=")) {
254: name = arg.substring(6);
255: verboseOut.println("name=" + name);
256: } else {
257: out.println("Unknow argument: " + arg);
258: }
259: }
260: try {
261: admin.removeUser(name);
262: } catch (UserManagerExc e) {
263: out.println("Unable to remove user: " + e.getMessage());
264: }
265: }
266:
267: protected void allUsers(String[] _args) throws Exception {
268: DxCollection users = null;
269: try {
270: users = admin.allUsers();
271: } catch (UserManagerExc e) {
272: out.println("Unable to retrieve all users: "
273: + e.getMessage());
274: }
275: if (users.isEmpty()) {
276: out.println("No users found.");
277: } else {
278: for (DxIterator it = users.iterator(); it.next() != null;) {
279: User user = (User) it.object();
280:
281: out.println("user name: " + user.name());
282: out.println(" id: " + user.id());
283: }
284: }
285:
286: }
287:
288: protected void newGroup(String[] _args) throws Exception {
289: String name = null;
290: int id = -1;
291:
292: // check command line arguments
293: for (int i = 1; i < _args.length; i++) {
294: String arg = _args[i];
295:
296: if (arg.startsWith("-name=")) {
297: name = arg.substring(6);
298: verboseOut.println("name=" + name);
299: } else if (arg.startsWith("-id=")) {
300: id = Integer.parseInt(arg.substring(4));
301: verboseOut.println("id=" + id);
302: } else {
303: out.println("Unknow argument: " + arg);
304: }
305: }
306: try {
307: admin.newGroup(name, id);
308: } catch (UserManagerExc e) {
309: out
310: .println("Unable to create new group: "
311: + e.getMessage());
312: }
313: }
314:
315: protected void removeGroup(String[] _args) throws Exception {
316: String name = null;
317:
318: // check command line arguments
319: for (int i = 1; i < _args.length; i++) {
320: String arg = _args[i];
321:
322: if (arg.startsWith("-name=")) {
323: name = arg.substring(6);
324: verboseOut.println("name=" + name);
325: } else {
326: out.println("Unknow argument: " + arg);
327: }
328: }
329: try {
330: admin.removeGroup(name);
331: } catch (UserManagerExc e) {
332: out.println("Unable to remove group: " + e.getMessage());
333: }
334: }
335:
336: protected void allGroups(String[] _args) throws Exception {
337: DxCollection groups = null;
338: try {
339: groups = admin.allGroups();
340: } catch (UserManagerExc e) {
341: out.println("Unable to retrieve all groups: "
342: + e.getMessage());
343: return;
344: }
345: if (groups.isEmpty()) {
346: out.println("No groups found.");
347: } else {
348: for (DxIterator it = groups.iterator(); it.next() != null;) {
349: Group group = (Group) it.object();
350:
351: out.println("group name: " + group.name());
352: out.println(" id: " + group.id());
353: out.println(" user ID count: " + group.usersCount());
354:
355: DxIterator it2 = group.userIDs().iterator();
356: int c = 1;
357: String line = " user IDs: ";
358: while (it2.next() != null) {
359: line += (c > 1 ? ", " : "");
360: line += it2.object().toString();
361: if (c++ % 10 == 0) {
362: out.println(line);
363: line = " ";
364: }
365: }
366: out.println(line);
367: }
368: }
369: }
370:
371: protected void addUser2Group(String[] _args) throws Exception {
372: String username = null;
373: String groupname = null;
374:
375: // check command line arguments
376: for (int i = 1; i < _args.length; i++) {
377: String arg = _args[i];
378:
379: if (arg.startsWith("-username=")) {
380: username = arg.substring(10);
381: verboseOut.println("user name=" + username);
382: } else if (arg.startsWith("-groupname=")) {
383: groupname = arg.substring(11);
384: verboseOut.println("group name=" + groupname);
385: } else {
386: out.println("Unknow argument: " + arg);
387: }
388: }
389: try {
390: admin.addUser2Group(username, groupname);
391: } catch (UserManagerExc e) {
392: out.println("Unable to add user to group: "
393: + e.getMessage());
394: }
395: }
396:
397: protected void numberOfTxs() throws Exception {
398: out.println(admin.numberOfTxs());
399: }
400:
401: protected void shutdown() throws Exception {
402: admin.shutdown();
403: }
404:
405: protected void startGarbageCollection() {
406: admin.startGarbageCollection();
407: }
408:
409: protected void restore(String[] _args) throws Exception {
410: String filename = "-";
411: boolean compress = false;
412:
413: // check command line arguments
414: for (int i = 1; i < _args.length; i++) {
415: String arg = _args[i];
416:
417: if (arg.equals("-compress")) {
418: compress = true;
419: verboseOut.println("compress=" + compress);
420: } else if (arg.startsWith("-infile=")) {
421: filename = arg.substring(8);
422: verboseOut.println("filename=" + filename);
423: } else {
424: out.println("Unknow argument: " + arg);
425: }
426: }
427:
428: try {
429: admin.beginRestore();
430:
431: InputStream in = System.in;
432: if (!filename.equals("-")) {
433: in = new FileInputStream(filename);
434: }
435: if (compress) {
436: in = new GZIPInputStream(in, 4096);
437: } else {
438: in = new BufferedInputStream(in, 4096);
439: }
440: InputSource xmlSource = new InputSource(in);
441:
442: SAXChunkProducer producer = new SAXChunkProducer(this );
443:
444: SAXParserFactory parserFactory = SAXParserFactory
445: .newInstance();
446: SAXParser parser = parserFactory.newSAXParser();
447: ParserAdapter adapter = new ParserAdapter(parser
448: .getParser());
449: adapter.setContentHandler(producer);
450: adapter.parse(xmlSource);
451: } catch (Exception e) {
452: out
453: .println("\nAn error occured while restoring the database.");
454: out
455: .println("The database is not entirely restored and is probably not usable!");
456: out.println("Please completely install and restore again.");
457: out.println("");
458: e.printStackTrace(out);
459: } finally {
460: // signal end
461: admin.processRestoreChunk(null);
462: }
463: }
464:
465: /**
466: * This method is inherited from SAXChunkProducerDelegate. It is called
467: * by the producer when a chunk is ready to be processed.
468: */
469: public void processChunk(SAXChunkProducer _producer)
470: throws Exception {
471: admin
472: .processRestoreChunk(_producer.chunkStream()
473: .toByteArray());
474: }
475:
476: protected void backup(String[] _args) throws Exception {
477: String filename = "-";
478: boolean indent = false;
479: boolean raw = false;
480: boolean compress = false;
481:
482: // check command line arguments
483: for (int i = 1; i < _args.length; i++) {
484: String arg = _args[i];
485:
486: if (arg.equals("-compress")) {
487: compress = true;
488: verboseOut.println("compress=" + compress);
489: } else if (arg.equals("-indent")) {
490: indent = true;
491: verboseOut.println("indent=" + indent);
492: } else if (arg.equals("-raw")) {
493: raw = true;
494: verboseOut.println("raw=" + raw);
495: } else if (arg.startsWith("-outfile=")) {
496: filename = arg.substring(9);
497: verboseOut.println("filename=" + filename);
498: } else {
499: out.println("Unknow argument: " + arg);
500: }
501: }
502:
503: ExternalTransaction tx = db.newTransaction();
504: tx.begin();
505: try {
506: admin.beginBackup();
507:
508: OutputStream out = System.out;
509: if (!filename.equals("-")) {
510: out = new FileOutputStream(filename);
511: }
512: if (compress) {
513: out = new GZIPOutputStream(out, 4096);
514: } else {
515: out = new BufferedOutputStream(out, 4096);
516: }
517:
518: XMLSerializer serializer = new XMLSerializer(out,
519: new OutputFormat("xml", "UTF-8", indent));
520: SAXChunkConsumer consumer = new SAXChunkConsumer(serializer
521: .asContentHandler());
522:
523: byte[] bytes = null;
524: while ((bytes = admin.nextBackupChunk()) != null) {
525: consumer.processChunk(bytes);
526: }
527: if (out instanceof GZIPOutputStream) {
528: ((GZIPOutputStream) out).finish();
529: }
530: out.close();
531: } finally {
532: tx.rollback();
533: }
534: }
535:
536: }
|