1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: AccessExample.java,v 12.8 2008/02/07 17:12:19 mark Exp $
7 */
8
9package collections.access;
10
11import java.io.File;
12import java.io.FileNotFoundException;
13import java.io.IOException;
14import java.io.InputStreamReader;
15import java.io.PrintStream;
16import java.util.Iterator;
17import java.util.Map;
18import java.util.SortedMap;
19
20import com.sleepycat.bind.ByteArrayBinding;
21import com.sleepycat.collections.StoredSortedMap;
22import com.sleepycat.collections.TransactionRunner;
23import com.sleepycat.collections.TransactionWorker;
24import com.sleepycat.db.Database;
25import com.sleepycat.db.DatabaseConfig;
26import com.sleepycat.db.DatabaseException;
27import com.sleepycat.db.DatabaseType;
28import com.sleepycat.db.Environment;
29import com.sleepycat.db.EnvironmentConfig;
30
31/**
32 *  AccesssExample mirrors the functionality of a class by the same name
33 * used to demonstrate the com.sleepycat.je Java API. This version makes
34 * use of the new com.sleepycat.collections.* collections style classes to make
35 * life easier.
36 *
37 *@author     Gregory Burd
38 *@created    October 22, 2002
39 */
40public class AccessExample
41         implements Runnable {
42
43    // Class Variables of AccessExample class
44    private static boolean create = true;
45    private static final int EXIT_SUCCESS = 0;
46    private static final int EXIT_FAILURE = 1;
47
48    public static void usage() {
49
50	System.out.println("usage: java " + AccessExample.class.getName() +
51            " [-r] [database]\n");
52	System.exit(EXIT_FAILURE);
53    }
54
55    /**
56     *  The main program for the AccessExample class
57     *
58     *@param  argv  The command line arguments
59     */
60    public static void main(String[] argv) {
61
62	boolean removeExistingDatabase = false;
63	String databaseName = "access.db";
64
65	for (int i = 0; i < argv.length; i++) {
66	    if (argv[i].equals("-r")) {
67		removeExistingDatabase = true;
68	    } else if (argv[i].equals("-?")) {
69		usage();
70	    } else if (argv[i].startsWith("-")) {
71		usage();
72	    } else {
73		if ((argv.length - i) != 1)
74		    usage();
75		databaseName = argv[i];
76		break;
77	    }
78	}
79
80        try {
81
82            EnvironmentConfig envConfig = new EnvironmentConfig();
83            envConfig.setTransactional(true);
84            envConfig.setInitializeCache(true);
85            envConfig.setInitializeLocking(true);
86            if (create) {
87                envConfig.setAllowCreate(true);
88            }
89            Environment env = new Environment(new File("."), envConfig);
90	    // Remove the previous database.
91	    if (removeExistingDatabase) {
92                env.removeDatabase(null, databaseName, null);
93            }
94
95            // create the app and run it
96            AccessExample app = new AccessExample(env, databaseName);
97            app.run();
98        } catch (DatabaseException e) {
99            e.printStackTrace();
100            System.exit(1);
101        } catch (FileNotFoundException e) {
102            e.printStackTrace();
103            System.exit(1);
104        } catch (Exception e) {
105            e.printStackTrace();
106            System.exit(1);
107        }
108        System.exit(0);
109    }
110
111
112    private Database db;
113    private SortedMap map;
114    private Environment env;
115
116
117    /**
118     *  Constructor for the AccessExample object
119     *
120     *@param  env            Description of the Parameter
121     *@exception  Exception  Description of the Exception
122     */
123    public AccessExample(Environment env, String databaseName)
124	throws Exception {
125
126        this.env = env;
127
128        //
129        // Lets mimic the db.AccessExample 100%
130        // and use plain old byte arrays to store the key and data strings.
131        //
132        ByteArrayBinding keyBinding = new ByteArrayBinding();
133        ByteArrayBinding dataBinding = new ByteArrayBinding();
134
135        //
136        // Open a data store.
137        //
138        DatabaseConfig dbConfig = new DatabaseConfig();
139        if (create) {
140            dbConfig.setAllowCreate(true);
141            dbConfig.setType(DatabaseType.BTREE);
142        }
143        this.db = env.openDatabase(null, databaseName, null, dbConfig);
144
145        //
146        // Now create a collection style map view of the data store
147        // so that it is easy to work with the data in the database.
148        //
149        this.map = new StoredSortedMap(db, keyBinding, dataBinding, true);
150    }
151
152
153    /**
154     *  Main processing method for the AccessExample object
155     */
156    public void run() {
157        //
158        // Insert records into a Stored Sorted Map DatabaseImpl, where
159        // the key is the user input and the data is the user input
160        // in reverse order.
161        //
162        final InputStreamReader reader = new InputStreamReader(System.in);
163
164        for (; ; ) {
165            final String line = askForLine(reader, System.out, "input> ");
166            if (line == null) {
167                break;
168            }
169
170            final String reversed =
171		(new StringBuffer(line)).reverse().toString();
172
173            log("adding: \"" +
174		line + "\" : \"" +
175		reversed + "\"");
176
177            // Do the work to add the key/data to the HashMap here.
178            TransactionRunner tr = new TransactionRunner(env);
179            try {
180                tr.run(
181		       new TransactionWorker() {
182			   public void doWork() {
183			       if (!map.containsKey(line.getBytes()))
184				   map.put(line.getBytes(),
185                                           reversed.getBytes());
186			       else
187				   System.out.println("Key " + line +
188						      " already exists.");
189			   }
190		       });
191            } catch (com.sleepycat.db.DatabaseException e) {
192                System.err.println("AccessExample: " + e.toString());
193                System.exit(1);
194            } catch (java.lang.Exception e) {
195                System.err.println("AccessExample: " + e.toString());
196                System.exit(1);
197            }
198        }
199        System.out.println("");
200
201        // Do the work to traverse and print the HashMap key/data
202        // pairs here get iterator over map entries.
203        Iterator iter = map.entrySet().iterator();
204        System.out.println("Reading data");
205        while (iter.hasNext()) {
206            Map.Entry entry = (Map.Entry) iter.next();
207            log("found \"" +
208                new String((byte[]) entry.getKey()) +
209                "\" key with data \"" +
210                new String((byte[]) entry.getValue()) + "\"");
211        }
212    }
213
214
215    /**
216     *  Prompts for a line, and keeps prompting until a non blank line is
217     *  returned. Returns null on error.
218     *
219     *@param  reader  stream from which to read user input
220     *@param  out     stream on which to prompt for user input
221     *@param  prompt  prompt to use to solicit input
222     *@return         the string supplied by the user
223     */
224    String askForLine(InputStreamReader reader, PrintStream out,
225                      String prompt) {
226
227        String result = "";
228        while (result != null && result.length() == 0) {
229            out.print(prompt);
230            out.flush();
231            result = getLine(reader);
232        }
233        return result;
234    }
235
236
237    /**
238     *  Read a single line. Gets the line attribute of the AccessExample object
239     *  Not terribly efficient, but does the job. Works for reading a line from
240     *  stdin or a file.
241     *
242     *@param  reader  stream from which to read the line
243     *@return         either a String or null on EOF, if EOF appears in the
244     *      middle of a line, returns that line, then null on next call.
245     */
246    String getLine(InputStreamReader reader) {
247
248        StringBuffer b = new StringBuffer();
249        int c;
250        try {
251            while ((c = reader.read()) != -1 && c != '\n') {
252                if (c != '\r') {
253                    b.append((char) c);
254                }
255            }
256        } catch (IOException ioe) {
257            c = -1;
258        }
259
260        if (c == -1 && b.length() == 0) {
261            return null;
262        } else {
263            return b.toString();
264        }
265    }
266
267
268    /**
269     *  A simple log method.
270     *
271     *@param  s  The string to be logged.
272     */
273    private void log(String s) {
274
275        System.out.println(s);
276        System.out.flush();
277    }
278}
279