001: /* Copyright 2004 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.services.persondir.support.legacy;
007:
008: import java.util.Collections;
009: import java.util.HashMap;
010: import java.util.HashSet;
011: import java.util.List;
012: import java.util.Map;
013: import java.util.Set;
014:
015: import javax.sql.DataSource;
016:
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019: import org.jasig.portal.RDBMServices;
020: import org.jasig.portal.ldap.ILdapServer;
021: import org.jasig.portal.ldap.LdapServerImpl;
022: import org.jasig.portal.ldap.LdapServices;
023: import org.jasig.portal.security.IPerson;
024: import org.jasig.portal.services.persondir.IPersonAttributeDao;
025: import org.jasig.portal.services.persondir.support.JdbcPersonAttributeDaoImpl;
026: import org.jasig.portal.services.persondir.support.LdapPersonAttributeDaoImpl;
027: import org.springframework.jdbc.datasource.DriverManagerDataSource;
028: import org.springframework.jndi.JndiObjectFactoryBean;
029:
030: /**
031: * Adapts from a {@link PersonDirInfo} to a {@link IPersonAttributeDao}.
032: *
033: * @author andrew.petro@yale.edu
034: * @version $Revision: 35856 $ $Date: 2005-05-25 10:16:44 -0700 (Wed, 25 May 2005) $
035: * @since uPortal 2.5
036: */
037: final class PersonDirInfoAdaptor {
038: private static final Log LOG = LogFactory
039: .getLog(PersonDirInfoAdaptor.class);
040:
041: //Needed since our Jdbc Dao needs an attribute to map queries with
042: protected static final String QUERY_ATTRIBUTE = IPerson.USERNAME;
043: private static final List QUERY_ATTRIBUTE_LIST = Collections
044: .singletonList(QUERY_ATTRIBUTE);
045:
046: /**
047: * Return an IPersonAttributeDao implementing the source defined
048: * by the given PersonDirInfo. Throws IllegalArgumentException if the
049: * given info doesn't define a valid IPersonAttributeDao (and this class
050: * succeeds in detecting the problem).
051: *
052: * @param info PersonDirInfo defining the attribute source we implement
053: * @throws IllegalArgumentException
054: * @return an IPersonAttributeDao implementing the defined source
055: */
056: static IPersonAttributeDao adapt(final PersonDirInfo info) {
057: if (LOG.isTraceEnabled())
058: LOG.trace("entering adapt(" + info + ")");
059:
060: if (info == null)
061: throw new IllegalArgumentException("info cannot be null.");
062:
063: final String validityMessage = info.validate();
064: if (validityMessage != null) {
065: throw new IllegalArgumentException(
066: "The PersonDirInfo to be adapted has illegal state: "
067: + validityMessage);
068: }
069:
070: IPersonAttributeDao returnMe = null;
071:
072: if (info.isJdbc()) {
073: returnMe = jdbcDao(info);
074: } else if (info.isLdap()) {
075: returnMe = ldapDao(info);
076: } else {
077: throw new IllegalArgumentException(
078: "Provided PersonDirInfo is not JDBC or LDAP, unable to adapt:"
079: + info);
080: }
081:
082: if (returnMe == null) {
083: throw new IllegalStateException(
084: "There was an unknown problem creating the IPersonAttributeDao delegate - it came out null!");
085: }
086:
087: if (LOG.isTraceEnabled())
088: LOG.trace("constructed " + returnMe);
089:
090: return returnMe;
091: }
092:
093: /**
094: * Obtain a {@link JdbcPersonAttributeDaoImpl} for the given {@link PersonDirInfo}.
095: *
096: * @param info The {@link PersonDirInfo} to use as a basis for the DAO
097: * @return A fully configured {@link JdbcPersonAttributeDaoImpl}
098: */
099: private static IPersonAttributeDao jdbcDao(final PersonDirInfo info) {
100: final String sql = info.getUidquery();
101:
102: // determine where to get our DataSource
103: DataSource source = null;
104:
105: final String dsRefName = info.getResRefName();
106: if (dsRefName != null && dsRefName.length() > 0) {
107:
108: if (dsRefName.equals(RDBMServices.DEFAULT_DATABASE)) {
109: // get a DataSource from RDBMServices
110: source = RDBMServices.getDataSource(dsRefName);
111: } else {
112: JndiObjectFactoryBean factory = new JndiObjectFactoryBean();
113: factory.setJndiName("jdbc/" + dsRefName);
114: factory.setResourceRef(true);
115:
116: try {
117: factory.afterPropertiesSet();
118: source = (DataSource) factory.getObject();
119: } catch (Exception t) {
120: LOG.error("Error looking up datasource ["
121: + dsRefName + "] from JNDI.", t);
122: throw new IllegalArgumentException(
123: "Referenced JNDI name did not map to a DataSource.");
124: }
125:
126: }
127:
128: } else {
129: // construct a DataSource adhoc
130: DriverManagerDataSource ds = new DriverManagerDataSource();
131: ds.setDriverClassName(info.getDriver());
132: ds.setUsername(info.getLogonid());
133: ds.setPassword(info.getLogonpassword());
134: ds.setUrl(info.getUrl());
135:
136: source = ds;
137: }
138:
139: final JdbcPersonAttributeDaoImpl jdbcImpl = new JdbcPersonAttributeDaoImpl(
140: source, QUERY_ATTRIBUTE_LIST, sql);
141:
142: // Map from JDBC column names to Sets of Strings representing uPortal
143: // attribute names.
144: final Map jdbcToPortalAttribs = new HashMap();
145:
146: final String[] columnNames = info.getAttributenames();
147: final String[] portalAttribNames = info.getAttributealiases();
148:
149: for (int i = 0; i < columnNames.length; i++) {
150: final String columnName = columnNames[i];
151:
152: if (columnName != null && columnName.length() > 0) {
153: Set attributeNames = (Set) jdbcToPortalAttribs
154: .get(columnName);
155:
156: if (attributeNames == null)
157: attributeNames = new HashSet();
158:
159: attributeNames.add(portalAttribNames[i]);
160: jdbcToPortalAttribs.put(columnName, attributeNames);
161: }
162: }
163:
164: jdbcImpl.setColumnsToAttributes(jdbcToPortalAttribs);
165: jdbcImpl.setDefaultAttributeName(QUERY_ATTRIBUTE);
166:
167: return jdbcImpl;
168: }
169:
170: /**
171: * Obtain a {@link LdapPersonAttributeDaoImpl} for the given {@link PersonDirInfo}.
172: *
173: * @param info The {@link PersonDirInfo} to use as a basis for the DAO
174: * @return A fully configured {@link LdapPersonAttributeDaoImpl}
175: */
176: private static IPersonAttributeDao ldapDao(final PersonDirInfo info) {
177: final LdapPersonAttributeDaoImpl ldapImpl = new LdapPersonAttributeDaoImpl();
178:
179: ILdapServer ldapServer = null;
180:
181: final String ldapRefName = info.getLdapRefName();
182: if (ldapRefName != null) {
183: ldapServer = LdapServices.getLdapServer(ldapRefName);
184:
185: if (ldapServer == null)
186: throw new IllegalArgumentException(
187: "LdapServices does not have an LDAP server configured with name ["
188: + ldapRefName + "]");
189: } else {
190: // instantiate an LDAP server ad-hoc.
191:
192: // set the "usercontext" attribute of the PersonDirInfo as the baseDN
193: // of the LdapServerImpl we're instantiating because when
194: ldapServer = new LdapServerImpl(info.getUrl(), info
195: .getUrl(), info.getUsercontext(), null, info
196: .getLogonid(), info.getLogonpassword(), null);
197: }
198:
199: ldapImpl.setLdapServer(ldapServer);
200: ldapImpl.setTimeLimit(info.getLdaptimelimit());
201: ldapImpl.setQuery(info.getUidquery());
202: ldapImpl.setQueryAttributes(QUERY_ATTRIBUTE_LIST);
203:
204: // Map from LDAP attribute names to Sets of Strings representing uPortal
205: // attribute names.
206: final Map ldapToPortalAttribs = new HashMap();
207:
208: final String[] ldapAttribNames = info.getAttributenames();
209: final String[] portalAttribNames = info.getAttributealiases();
210: for (int i = 0; i < ldapAttribNames.length; i++) {
211: final String ldapAttribName = ldapAttribNames[i];
212:
213: Set attributeNames = (Set) ldapToPortalAttribs
214: .get(ldapAttribName);
215: if (attributeNames == null)
216: attributeNames = new HashSet();
217:
218: attributeNames.add(portalAttribNames[i]);
219: ldapToPortalAttribs.put(ldapAttribName, attributeNames);
220: }
221:
222: ldapImpl
223: .setLdapAttributesToPortalAttributes(ldapToPortalAttribs);
224: ldapImpl.setDefaultAttributeName(QUERY_ATTRIBUTE);
225:
226: return ldapImpl;
227: }
228:
229: /**
230: * This class is not intended to be instantiated, hence the private constructor.
231: */
232: private PersonDirInfoAdaptor() {
233: // this class is not intended to be instantiated
234: }
235: }
|