package mit.moira;
-public class MoiraConnect {
+public class Moira {
boolean connected = false;
boolean isauth = false;
- Object LOCK;
-
String server = "";
- MoiraConnect() {
+ boolean isValid = true;
+
+ protected static Object LOCK = new Object();
+ protected static boolean isAvailable = true;
+
+ public static Moira getInstance(String server) {
+ synchronized (LOCK) {
+ while (!isAvailable) {
+ try {
+ LOCK.wait();
+ } catch (InterruptedException ie) {
+ }
+ }
+ isAvailable = false;
+ return new Moira(server);
+ }
+ }
+
+ protected static void returnInstance() {
+ synchronized(LOCK) {
+ isAvailable = true;
+ LOCK.notify();
+ }
}
- public MoiraConnect(String server, Object lock) {
+ public synchronized void done() {
+ if (!isValid) return; // Don't make noise...
+ try {
+ disconnect();
+ } catch (MoiraException m) {
+ }
+ isValid = false;
+ returnInstance();
+ }
+
+ protected Moira() {
+ }
+
+ protected Moira(String server) {
this.server = server;
- this.LOCK = lock;
}
- public void connect() throws MoiraException {
+ public synchronized void connect() throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!connected) {
MoiraConnectInternal.connect(server);
connected = true;
}
}
- public void auth() throws MoiraException {
+ public synchronized void auth() throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!isauth) {
synchronized(LOCK) {
MoiraConnectInternal.auth();
}
}
- public void proxy(String user) throws MoiraException {
+ public synchronized void proxy(String user) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
MoiraConnectInternal.proxy(user);
}
- public void disconnect() {
+ public synchronized void disconnect() throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (connected) {
MoiraConnectInternal.disconnect();
connected = false;
}
}
- public ListInfo get_list_info(String list) throws MoiraException {
+ public synchronized ListInfo get_list_info(String list) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!connected) throw new MoiraException("Not Connected");
String [] args = new String[1];
args[0] = list;
return (new ListInfo(entry[0], entry[1], entry[2], entry[3], entry[4], entry[5], entry[6], entry[7], entry[8], entry[9], entry[10], entry[11], entry[12]));
}
- void update_list_info(String list, ListInfo info) throws MoiraException {
+ public synchronized void update_list_info(String list, ListInfo info) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!connected) throw new MoiraException("Not Connected");
String [] args = new String[11];
args[0] = list;
return;
}
- void delete_member_from_list(String list, String type, String member) throws MoiraException {
+ public synchronized void delete_member_from_list(String list, String type, String member) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!connected) throw new MoiraException("Not Connected");
String [] args = new String[3];
args[0] = list;
return;
}
- void add_member_to_list(String list, String type, String member) throws MoiraException {
+ public synchronized void add_member_to_list(String list, String type, String member) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!connected) throw new MoiraException("Not Connected");
String [] args = new String[3];
args[0] = list;
return;
}
- public Member [] get_members_of_list(String list) throws MoiraException {
+ public synchronized String [] get_user_by_login(String user) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
+ if (!connected) throw new MoiraException("Not Connected");
+ String [] args = new String[1];
+ args[0] = user;
+ Object [] retinternal = MoiraConnectInternal.mr_query("get_user_by_login", args);
+ if (retinternal == null) return (null);
+ String [] entry = (String []) retinternal[0];
+ return(entry);
+ }
+
+ public synchronized Member [] get_members_of_list(String list) throws MoiraException {
+ if (!isValid) throw new MoiraException("Attempt to use stale Moira Object");
if (!connected) throw new MoiraException("Not Connected");
String [] args = new String[1];
args[0] = list;
}
return (retval);
}
+
+ public void finalize() {
+ if (isValid) System.err.println("Moira object finalized while valid!");
+ else System.err.println("Moira object finalized (normally)");
+ }
+
}
class MoiraConnectInternal {
public class MoiraServlet extends HttpServlet {
static final String MOIRA_SERVER = "moira.mit.edu";
- Object LOCK = new Object(); // Used to synchronize Moira authentication
- // with the ticket fetching thread
- Kticket kt = new Kticket("jis5", "foobar", "ATHENA.MIT.EDU", LOCK);
+ Kticket kt = new Kticket("jis5", "foobar", "ATHENA.MIT.EDU");
boolean ktinit = false;
private static final int MAXDISPLAY = 10;
Hashtable FileParts = new Hashtable();
if (offset < 0) showall = true;
if (members == null) {
- MoiraConnect mc = null;
+ Moira mc = null;
try {
mc = connect();
mc.proxy(kname);
members = mc.get_members_of_list(arg);
- mc.disconnect();
+ mc.done(); // Done will disconnect
mc = null;
if (members != null)
session.putValue("members", members);
e.printStackTrace();
}
} finally {
- if (mc != null) mc.disconnect();
+ if (mc != null) mc.done();
}
}
}
for (int i = offset; i < len; i++) {
msg += "<tr><td>" + members[i].getMemberType() + "</td>";
- msg += "<td>" + members[i].getMemberId() + "</td></tr>\r\n";
+ msg += "<td>" + quote(members[i].getMemberId()) + "</td></tr>\r\n";
}
msg += "</table></td><td> </td></tr><tr>\r\n";
if ((offset > 0) && !showall) {
HttpSession session = request.getSession(true);
- MoiraConnect mc = null;
+ Moira mc = null;
ListInfo li = null;
try {
mc = connect();
msg += "!>\r\n";
return (msg);
} finally {
- try {
- if (mc != null) mc.disconnect();
- mc = null;
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
String list_description = "";
HttpSession session = request.getSession(true);
- MoiraConnect mc = null;
+ Moira mc = null;
boolean found = false;
boolean sublists = false;
Member [] members = null;
}
}
}
- mc.disconnect();
- mc = null;
} catch (MoiraException m) {
try {
msg = "<P><b>\r\n";
e.printStackTrace();
}
} finally {
- if (mc != null) mc.disconnect();
+ if (mc != null) mc.done();
}
msg = "You are " + (found ? "" : "not ") + "a member of the list <b>" + arg + "</b>.<br>\r\n";
if (!found && sublists)
if (listname == null) {
return("<p>Could not find list name (shouldn't happen).</p>");
}
- MoiraConnect mc = null;
+ Moira mc = null;
try {
mc = connect();
mc.proxy(kname);
msg += "!>\r\n";
return (msg);
} finally {
- try {
- if (mc != null) mc.disconnect();
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
if (add) msg = "You have been added to the <b>" + listname + "</b> list.";
else msg = "You have been removed from the <b>" + listname + "</b> list.";
HttpSession session = request.getSession(true);
- MoiraConnect mc = null;
+ Moira mc = null;
try {
mc = connect();
mc.proxy(kname);
for (int i = 0; i < members.length; i++) {
del[i] = new Delmember(members[i]);
}
- mc.disconnect();
+ mc.done();
mc = null;
session.putValue("list", arg);
session.removeValue("members"); // In case left over from previous call
e.printStackTrace();
}
} finally {
- if (mc != null) mc.disconnect();
+ if (mc != null) mc.done();
}
return (do_remdisplay(qv, request, response, del, 0));
}
msg += "<tr><td><input type=checkbox name=selected value=\" " + i + "\"";
if (del[i].marked) msg += " checked";
msg += "></td><td>" + del[i].member.getMemberType() + "</td>";
- msg += "<td>" + del[i].member.getMemberId() + "</td></tr>\r\n";
+ msg += "<td>" + quote(del[i].member.getMemberId()) + "</td></tr>\r\n";
}
msg += "</table></td>\r\n";
msg += "<td><input type=hidden name=operation value=delmembers></td></tr>\r\n";
for (int i = 0; i < del.length; i++) {
if (del[i].marked) {
msg += "<tr><td>" + del[i].member.getMemberType() + "</td>";
- msg += "<td>" + del[i].member.getMemberId() + "</td></tr>\r\n";
+ msg += "<td>" + quote(del[i].member.getMemberId()) + "</td></tr>\r\n";
}
}
msg += "</table>\r\n";
Vector problems = new Vector();
Vector success = new Vector();
- MoiraConnect mc = null;
+ Moira mc = null;
try {
mc = connect();
mc.proxy(kname);
success.addElement(del[i].member);
}
} catch (MoiraException m) {
- problems.addElement("<tr><td>" + del[i].member.getMemberId() + "</td><td>" + m.getMessage() + "</td></tr>\r\n");
+ problems.addElement("<tr><td>" + quote(del[i].member.getMemberId()) + "</td><td>" + m.getMessage() + "</td></tr>\r\n");
}
}
} catch (MoiraException m) {
msg += "!>\r\n";
return (msg);
} finally {
- try {
- if (mc != null) mc.disconnect();
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
msg = "";
msg += "<h2>Deleted the following:</h2>\r\n";
msg += "<table border=1 cellpadding=2>\r\n";
for (int i = 0; i < success.size(); i++) {
- msg += "<tr><td>" + ((Member)success.elementAt(i)).getMemberId() + "</td></tr>\r\n";
+ msg += "<tr><td>" + quote(((Member)success.elementAt(i)).getMemberId()) + "</td></tr>\r\n";
}
msg += "</table>\r\n";
}
HttpSession session = request.getSession(true);
String msg = "";
- MoiraConnect mc = null;
+ Moira mc = null;
ListInfo li = null;
try {
mc = connect();
msg += "!>\r\n";
return (msg);
} finally {
- try {
- if (mc != null) mc.disconnect();
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
if (li == null) {
return("Did not find list info.");
HttpSession session = request.getSession(true);
String msg = "";
- MoiraConnect mc = null;
+ Moira mc = null;
ListInfo li = null;
try {
mc = connect();
msg += "!>\r\n";
return (msg);
} finally {
- try {
- if (mc != null) mc.disconnect();
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
if (li == null) {
return("Did not find list info.");
if (tmp != null)
li.ace_name = tmp;
- MoiraConnect mc = null;
+ Moira mc = null;
try {
mc = connect();
mc.proxy(kname);
mc.update_list_info(li.name, li);
- mc.disconnect();
- mc = null;
} catch (MoiraException e) {
String msg;
if (e.getMessage().startsWith("No such list")) {
msg += "!>\r\n";
return (msg);
} finally {
- try {
- if (mc != null) mc.disconnect();
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
String msg = "<b>Update of " + li.name + " succeeded</b><p>\r\n";
qv.put("list", li.name);
if (member == null || type == null || member.equals("")) {
return("<p>No names selected to be added!</p>");
}
- MoiraConnect mc = null;
+ Moira mc = null;
StreamTokenizer tk = null;
msg += "<table border=1 cellpadding=2>\r\n";
boolean addheader = false;
mc = connect();
mc.proxy(kname);
tk = new StreamTokenizer(new StringReader(member));
+ mc.done();
+ mc = null;
tk.wordChars('@', '@');
tk.wordChars('0', '9');
tk.wordChars('_', '_');
} catch (IOException e) {
e.printStackTrace(); // Shouldn't happen
} finally {
- try {
- if (mc != null) mc.disconnect();
- } catch (Exception e) {
- }
+ if (mc != null) mc.done();
}
if (problems.size() != 0) {
msg += "<p>There were difficulties adding the following users:<br>\r\n";
* @return A Moira Connection Object
* @exception MoiraException on any error
*/
- protected MoiraConnect connect() throws MoiraException {
- MoiraConnect retval = null;
+ protected Moira connect() throws MoiraException {
+ Moira retval = null;
+ boolean error = true;
int count = 0;
- while (count++ < 10) { // Got to stop at some point!
- retval = new MoiraConnect(MOIRA_SERVER, LOCK);
- retval.connect();
- try {
- retval.auth();
- return (retval); // No exception, return. yeah!
- } catch (MoiraException m) {
- if ((m.getCode() != KE_RD_AP_BADD) || (count > 8)) {
- if (retval != null) {
- try {
- retval.disconnect();
- } catch (Exception e) {
- }
+ try {
+ while (count++ < 10) { // Got to stop at some point!
+ retval = Moira.getInstance(MOIRA_SERVER);
+ retval.connect();
+ try {
+ retval.auth();
+ error = false;
+ return (retval); // No exception, return. yeah!
+ } catch (MoiraException m) {
+ if ((m.getCode() != KE_RD_AP_BADD) || (count > 8)) {
+ throw m; // Re-throw if not the error we expect or we are looping
}
- throw m; // Re-throw if not the error we expect or we are looping
}
- }
- if (retval != null) {
- try {
- retval.disconnect();
- } catch (Exception e) {
+ if (retval != null) {
+ retval.done();
+ retval = null;
}
- retval = null;
+ System.err.println("MoiraServlet: Forced Renewal...");
+ kt.renew(); // Renew tickets
}
- System.err.println("MoiraServlet: Forced Renewal...");
- kt.renew(); // Renew tickets
+ // Fell through, count exceeded
+ throw new MoiraException("Cannot authenticate successfully to Moira");
+ } finally {
+ if (error && (retval != null)) retval.done();
}
- return (null);
}
+ public static String quote(String value) {
+ if (value.indexOf('<') == -1 &&
+ value.indexOf('>') == -1) return (value); // Nothing to quote
+ StringBuffer buf = new StringBuffer(value.length() + 10);
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ if (c != '<' && c != '>') buf.append(c);
+ else {
+ if (c == '<') buf.append("<");
+ if (c == '>') buf.append(">");
+ }
+ }
+ return (new String(buf));
+ }
}
class Delmember {