001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.groups;
007:
008: import java.sql.Connection;
009: import java.sql.ResultSet;
010: import java.sql.SQLException;
011: import java.sql.Statement;
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.Map;
015:
016: import org.jasig.portal.RDBMServices;
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019:
020: /**
021: * Reference implementation of <code>IEntityNameFinder</code> for <code>IPersons</code>.
022: * @author Dan Ellentuck
023: * @version $Revision: 34931 $
024: */
025: public class ReferencePersonNameFinder implements IEntityNameFinder {
026: private static final Log log = LogFactory
027: .getLog(ReferencePersonNameFinder.class);
028:
029: // Singleton instance:
030: private static IEntityNameFinder singleton;
031:
032: // SQL Strings:
033: private static String USER_TABLE = "UP_USER";
034: private static String USER_ID_COLUMN = "USER_ID";
035: private static String USER_NAME_COLUMN = "USER_NAME";
036:
037: private static String DIRECTORY_TABLE = "UP_PERSON_DIR";
038: private static String DIRECTORY_FIRST_NAME_COLUMN = "FIRST_NAME";
039: private static String DIRECTORY_LAST_NAME_COLUMN = "LAST_NAME";
040: private static String DIRECTORY_USER_NAME_COLUMN = "USER_NAME";
041:
042: // Our cache of entity names:
043: private Map names;
044:
045: /**
046: * ReferenceIPersonNameFinder constructor comment.
047: */
048: private ReferencePersonNameFinder() throws SQLException {
049: super ();
050: initialize();
051: }
052:
053: /**
054: * Get names by user ID from UP_PERSON_DIR.
055: * @exception java.sql.SQLException
056: */
057: private Map getDirectoryNames() throws java.sql.SQLException {
058: Connection conn = null;
059: Statement stmnt = null;
060: Map directoryNames = new HashMap();
061: try {
062: conn = RDBMServices.getConnection();
063: try {
064: stmnt = conn.createStatement();
065:
066: String sql = getSelectDirectoryNamesSql();
067: if (log.isDebugEnabled())
068: log
069: .debug("ReferencePersonNameFinder.getDirectoryNames(): "
070: + sql);
071:
072: ResultSet rs = stmnt.executeQuery(sql);
073: while (rs.next()) {
074: String key = ""
075: + rs.getString(DIRECTORY_USER_NAME_COLUMN);
076: String fname = rs
077: .getString(DIRECTORY_FIRST_NAME_COLUMN);
078: String lname = rs
079: .getString(DIRECTORY_LAST_NAME_COLUMN);
080: if (fname == null) {
081: fname = "";
082: }
083: if (lname == null) {
084: lname = "";
085: }
086: String fullname = fname + " " + lname;
087: directoryNames.put(key, fullname);
088: }
089: } finally {
090: stmnt.close();
091: }
092: } catch (SQLException sqle) {
093: log.error(
094: "Error getting names by userid from UP_PERSON_DIR",
095: sqle);
096: throw sqle;
097: }
098:
099: finally {
100: RDBMServices.releaseConnection(conn);
101: }
102: return directoryNames;
103: }
104:
105: /**
106: * Given the key, returns the entity's name.
107: * @param key java.lang.String
108: */
109: public String getName(String key) throws Exception {
110: return (String) primGetNames().get(key);
111: }
112:
113: /**
114: * Given an array of keys, returns the names of the entities. If a key
115: * is not found, its name will be null.
116: * @param keys java.lang.String[]
117: */
118: public java.util.Map getNames(java.lang.String[] keys)
119: throws Exception {
120: Map selectedNames = new HashMap();
121: for (int i = 0; i < keys.length; i++) {
122: String name = (String) primGetNames().get(keys[i]);
123: selectedNames.put(keys[i], name);
124: }
125: return selectedNames;
126: }
127:
128: /**
129: * @return java.lang.String
130: */
131: private String getSelectDirectoryNamesSql() {
132: return "SELECT " + DIRECTORY_USER_NAME_COLUMN + ", "
133: + DIRECTORY_FIRST_NAME_COLUMN + ", "
134: + DIRECTORY_LAST_NAME_COLUMN + " FROM "
135: + DIRECTORY_TABLE;
136: }
137:
138: /**
139: * @return java.lang.String
140: */
141: private String getSelectUserNamesSql() {
142: return "SELECT " + USER_NAME_COLUMN + " FROM " + USER_TABLE;
143: }
144:
145: /**
146: * Returns the entity type for this <code>IEntityFinder</code>.
147: * @return java.lang.Class
148: */
149: public Class getType() {
150: return org.jasig.portal.security.IPerson.class;
151: }
152:
153: /**
154: * Get names by user ID from UP_USER.
155: * @exception java.sql.SQLException
156: */
157: private Map getUserNames() throws java.sql.SQLException {
158: Connection conn = null;
159: Statement stmnt = null;
160: Map userNames = new HashMap();
161: try {
162: conn = RDBMServices.getConnection();
163: try {
164: stmnt = conn.createStatement();
165:
166: String sql = getSelectUserNamesSql();
167: if (log.isDebugEnabled())
168: log
169: .debug("ReferencePersonNameFinder.getUserNames(): "
170: + sql);
171:
172: ResultSet rs = stmnt.executeQuery(sql);
173: while (rs.next()) {
174: String key = rs.getString(USER_NAME_COLUMN);
175: userNames.put(key, key);
176: }
177:
178: } finally {
179: stmnt.close();
180: }
181: } catch (SQLException sqle) {
182: log.error("Error getting names by user ID from UP_USER",
183: sqle);
184: throw sqle;
185: }
186:
187: finally {
188: RDBMServices.releaseConnection(conn);
189: }
190: return userNames;
191: }
192:
193: /**
194: * Loads the names cache. This may seem like a dumb way to do it (making two
195: * passes and merging the results) but it does avoid the outer join horror.
196: * In any event, local implementations may often use a directory service
197: * like LDAP.
198: * @exception java.sql.SQLException
199: */
200: private void initialize() throws java.sql.SQLException {
201: Map userNames = getUserNames(); // user name by user id
202: Map directoryNames = getDirectoryNames(); // full name by user name
203:
204: Iterator i = userNames.entrySet().iterator();
205: while (i.hasNext()) {
206: Map.Entry entry = (Map.Entry) i.next();
207: String directoryName = (String) directoryNames
208: .get((String) entry.getValue());
209: if (directoryName != null) {
210: entry.setValue(directoryName);
211: }
212: }
213: names = userNames;
214: }
215:
216: /**
217: * @return java.util.Map
218: */
219: private Map primGetNames() {
220: return names;
221: }
222:
223: /**
224: * @return IEntityNameFinder
225: */
226: public static synchronized IEntityNameFinder singleton()
227: throws SQLException {
228: if (singleton == null) {
229: singleton = new ReferencePersonNameFinder();
230: }
231: return singleton;
232: }
233:
234: /**
235: * Returns a String that represents the value of this object.
236: * @return a string representation of the receiver
237: */
238: public String toString() {
239: return "IEntityNameFinder for " + getType().getName();
240: }
241: }
|