KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > appserv > management > client > prefs > MemoryHashLoginInfoStore


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.appserv.management.client.prefs;
24 import java.io.BufferedReader JavaDoc;
25 import java.io.FileReader JavaDoc;
26 import java.io.FileWriter JavaDoc;
27 import java.io.BufferedWriter JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.net.URI JavaDoc;
31 import java.net.URISyntaxException JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Collection JavaDoc;
38 import java.util.Collections JavaDoc;
39 //TBD
40
import sun.misc.BASE64Decoder;
41 import sun.misc.BASE64Encoder;
42
43 /** A {@link LoginInfoStore} that reads the information from the default file ".asadminpass"
44  * and stores it as a map in the memory. It is not guaranteed that the concurrent
45  * modifications will yield consistent results. This class is <i> not </i> thread safe. The
46  * serial access has to be ensured by the callers.
47  * @since Appserver 9.0
48  */

49 public class MemoryHashLoginInfoStore implements LoginInfoStore {
50     
51     public static final String JavaDoc DEFAULT_STORE_NAME = ".asadminpass";
52     
53     private static final BASE64Encoder encoder = new BASE64Encoder();
54     private static final BASE64Decoder decoder = new BASE64Decoder();
55     
56     private Map JavaDoc<HostPortKey, LoginInfo> state;
57     private final File JavaDoc store;
58     /**
59      * Creates a new instance of MemoryHashLoginInfoStore. A side effect of calling
60      * this constructor is that if the default store does not exist, it will be created.
61      * This does not pose any harm or surprises.
62      */

63     public MemoryHashLoginInfoStore() throws StoreException {
64         BufferedReader JavaDoc br = null;
65         BufferedWriter JavaDoc bw = null;
66         try {
67             final File JavaDoc dir = new File JavaDoc (System.getProperty("user.home"));
68             store = new File JavaDoc(dir, DEFAULT_STORE_NAME);
69             if (!store.exists()) {
70                 store.createNewFile();
71                 bw = new BufferedWriter JavaDoc(new FileWriter JavaDoc(store));
72                 FileMapTransform.writePreamble(bw);
73                 state = new HashMap JavaDoc<HostPortKey, LoginInfo> ();
74             }
75             else {
76                 br = new BufferedReader JavaDoc(new FileReader JavaDoc(store));
77                 state = FileMapTransform.readAll(br);
78             }
79         }
80         catch(final Exception JavaDoc e) {
81             throw new StoreException(e);
82         }
83         finally {
84             try {
85                 if (br != null)
86                     br.close();
87             }
88             catch(final Exception JavaDoc ee) {}; //ignore
89
try {
90                 if (bw != null)
91                     bw.close();
92             }
93             catch(final Exception JavaDoc ee) {}; //ignore
94
}
95     }
96
97     public void store(final LoginInfo login) throws StoreException {
98         this.store(login, false);
99     }
100
101     public void store(final LoginInfo login, boolean overwrite) throws StoreException {
102         if (login == null)
103             throw new IllegalArgumentException JavaDoc("null_arg");
104         final String JavaDoc host = login.getHost();
105         final int port = login.getPort();
106         if (!overwrite && this.exists(host, port)) {
107             throw new StoreException("Login exists for host: " + host + " port: " + port);
108         }
109         final HostPortKey key = new HostPortKey(host, port);
110         final LoginInfo old = state.get(key);
111         state.put(key, login);
112         //System.out.println("committing: " + login);
113
commit(key, old);
114         protect();
115     }
116
117     public void remove(final String JavaDoc host, final int port) {
118         final HostPortKey key = new HostPortKey(host, port);
119         final LoginInfo gone = state.remove(key);
120         commit(key, gone);
121     }
122
123     public LoginInfo read(String JavaDoc host, int port) {
124         final HostPortKey key = new HostPortKey(host, port);
125         final LoginInfo login = state.get(key); //no need to access disk
126
return ( login );
127     }
128
129     public boolean exists(String JavaDoc host, int port) {
130         final HostPortKey key = new HostPortKey(host, port);
131         final boolean exists = state.containsKey(key); //no need to access disk
132
return ( exists );
133     }
134
135     public int size() {
136         return ( state.size() ); // no need to access disk
137
}
138
139     public Collection JavaDoc<LoginInfo> list() {
140         final Collection JavaDoc<LoginInfo> logins = state.values(); // no need to access disk
141
return (Collections.unmodifiableCollection(logins) );
142     }
143
144     public String JavaDoc getName() {
145         return ( store.getAbsoluteFile().getAbsolutePath() );
146     }
147     
148     ///// PRIVATE METHODS /////
149
private void commit(final HostPortKey key, LoginInfo old) {
150         BufferedWriter JavaDoc writer = null;
151         try {
152             //System.out.println("before commit");
153
writer = new BufferedWriter JavaDoc(new FileWriter JavaDoc(store));
154             FileMapTransform.writeAll(state.values(), writer);
155         }
156         catch(final Exception JavaDoc e) {
157             state.put(key, old); //try to roll back, first memory
158
try { // then disk, if the old value is not null
159
if (old != null) {
160                     writer = new BufferedWriter JavaDoc(new FileWriter JavaDoc(store));
161                     FileMapTransform.writeAll(state.values(), writer);
162                 }
163             }
164             catch(final Exception JavaDoc ae) {
165                 throw new RuntimeException JavaDoc("catastrophe, can't write it to file");
166             }//ignore, can't do much
167
}
168         finally {
169             try {
170                 writer.close();
171             } catch(final Exception JavaDoc ee) {} //ignore
172
}
173     }
174     
175     private void protect()
176     {
177         /*
178              note: if this is Windows we still try 'chmod' -- they may have MKS or
179             some other UNIXy package for Windows.
180             cacls is too dangerous to use because it requires a "Y" to be written to
181             stdin of the cacls process. If cacls doesn't exist or if they are using
182             a non-NTFS file system we would hang here forever.
183          */

184         try
185         {
186             if(store == null || !store.exists())
187                 return;
188
189             ProcessBuilder JavaDoc pb = new ProcessBuilder JavaDoc("chmod", "0600", store.getAbsolutePath());
190             pb.start();
191         }
192         catch(Exception JavaDoc e)
193         {
194             // we tried...
195
}
196     }
197
198     private static class FileMapTransform {
199         private FileMapTransform() {} //disallow
200
static Map JavaDoc<HostPortKey, LoginInfo> readAll(final BufferedReader JavaDoc reader) throws IOException JavaDoc, URISyntaxException JavaDoc {
201             String JavaDoc line = null;
202             final Map JavaDoc<HostPortKey, LoginInfo> map = new HashMap JavaDoc<HostPortKey, LoginInfo> ();
203             while ((line = reader.readLine()) != null) {
204                 if (line.startsWith("#"))
205                     continue; //ignore comments
206
final int si = line.indexOf(' '); //index of space
207
if (si == -1)
208                     throw new IOException JavaDoc("Error: invalid record: " + line);
209                 final URI JavaDoc uri = new URI JavaDoc(line.substring(0, si));
210                 final String JavaDoc encp = line.substring(si+1, line.length());
211                 final HostPortKey key = uri2Key(uri);
212                 final LoginInfo value = line2LoginInfo(uri, encp);
213                 map.put(key, value);
214             }
215             return ( map );
216         }
217         static void writeAll(final Collection JavaDoc<LoginInfo> logins, final BufferedWriter JavaDoc writer) throws IOException JavaDoc, URISyntaxException JavaDoc {
218             writePreamble(writer);
219             //write out sorted, because not more than 100 logins are expected to be there
220
final List JavaDoc<LoginInfo> list = new ArrayList JavaDoc<LoginInfo>(logins);
221             Collections.sort(list);
222             final Iterator JavaDoc<LoginInfo> it = list.iterator();
223             while (it.hasNext()) {
224                 final LoginInfo login = it.next();
225                 //System.out.println("wrote: " + login);
226
writeOne(login, writer);
227             }
228         }
229         private static void writeOne(final LoginInfo login, final BufferedWriter JavaDoc writer) throws IOException JavaDoc, URISyntaxException JavaDoc {
230             writer.write(login2Line(login));
231             writer.newLine();
232         }
233         static final HostPortKey uri2Key(final URI JavaDoc uri) {
234             final String JavaDoc host = uri.getHost();
235             final int port = uri.getPort();
236             final HostPortKey key = new HostPortKey(host, port);
237             return ( key );
238         }
239         static final LoginInfo line2LoginInfo(final URI JavaDoc uri, final String JavaDoc encp) throws IOException JavaDoc {
240             final String JavaDoc host = uri.getHost();
241             final int port = uri.getPort();
242             final String JavaDoc user = uri.getUserInfo();
243             final String JavaDoc password = new String JavaDoc(decoder.decodeBuffer(encp));
244             return ( new LoginInfo(host, port, user, password) );
245         }
246         static final String JavaDoc login2Line(final LoginInfo login) throws IOException JavaDoc, URISyntaxException JavaDoc {
247             final String JavaDoc scheme = "asadmin";
248             final String JavaDoc host = login.getHost();
249             final int port = login.getPort();
250             final String JavaDoc user = login.getUser();
251             final String JavaDoc path = null;
252             final String JavaDoc query = null;
253             final String JavaDoc frag = null;
254             final URI JavaDoc uri = new URI JavaDoc(scheme, user, host, port, path, query, frag);
255             final String JavaDoc password = login.getPassword();
256             final String JavaDoc encp = encoder.encode(password.getBytes());
257             final String JavaDoc line = uri.toString() + ' ' + encp;
258             
259             return ( line );
260         }
261         static void writePreamble(final BufferedWriter JavaDoc bw) throws IOException JavaDoc {
262             final String JavaDoc preamble = "# Do not edit this file by hand. Use login interface instead.";
263             bw.write(preamble);
264             bw.newLine();
265         }
266     }
267     
268     private static class HostPortKey {
269         private final String JavaDoc host;
270         private final int port;
271         HostPortKey(final String JavaDoc host, final int port) {
272             this.host = host;
273             this.port = port;
274         }
275         public boolean equals(final Object JavaDoc other) {
276             boolean same = false;
277             if (other instanceof HostPortKey) {
278                 final HostPortKey that = (HostPortKey)other;
279                 same = this.host.equals(that.host) && this.port == that.port;
280             }
281             return ( same );
282         }
283         public int hashCode() {
284             return ( (int) (53 * host.hashCode() + 31 * port) );
285         }
286     }
287 }
Popular Tags