001: /**
002: * Copyright 2003 Sun Microsystems, Inc. All
003: * rights reserved. Use of this product is subject
004: * to license terms. Federal Acquisitions:
005: * Commercial Software -- Government Users
006: * Subject to Standard License Terms and
007: * Conditions.
008: *
009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
010: * are trademarks or registered trademarks of Sun Microsystems,
011: * Inc. in the United States and other countries.
012: */package com.sun.portal.wsrp.producer;
013:
014: import java.util.Set;
015: import java.util.Map;
016: import java.util.HashSet;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.ArrayList;
020: import java.util.HashMap;
021: import java.util.logging.Level;
022: import java.util.logging.Logger;
023:
024: import java.io.ByteArrayInputStream;
025: import java.io.ByteArrayOutputStream;
026: import java.io.InputStream;
027: import java.io.UnsupportedEncodingException;
028:
029: import javax.xml.bind.JAXBException;
030:
031: import com.iplanet.sso.SSOToken;
032: import com.iplanet.sso.SSOTokenManager;
033: import com.iplanet.sso.SSOException;
034: import com.sun.identity.sm.ServiceListener;
035:
036: import com.sun.portal.wsrp.producer.ISConnection;
037:
038: import com.sun.portal.wsrp.common.jaxb.producer.ProducerRegistry;
039: import com.sun.portal.wsrp.common.jaxb.producer.ProducerRegistryElement;
040: import com.sun.portal.wsrp.common.jaxb.producer.ObjectFactory;
041: import com.sun.portal.log.common.PortalLogger;
042:
043: public class ProducerRegistryManager implements ISConstants {
044: private ProducerRegistryListener producerRegistryListener = null;
045: private ISConnection isConnection = null;
046: private ProducerJAXB producerJAXB = null;
047: private String portalId = null;
048: private ProducerRegistry producerRegistry = null;
049: private SSOToken token = null;
050: private static ProducerRegistryManager producerRegistryManager = null;
051:
052: private static Map registryManagerCache = new HashMap();
053: private static Logger logger = PortalLogger
054: .getLogger(ProducerRegistryManager.class);
055:
056: public class ProducerRegistryListener implements ServiceListener {
057: private ProducerRegistry producerRegistry = null;
058:
059: public ProducerRegistryListener() throws ProducerException {
060: isConnection.addConfigListener(this );
061:
062: //ISConnection.debug.error("ProducerRegistryListener.ProducerRegistryListener(): added listener");
063: }
064:
065: public ProducerRegistryListener(String portalId)
066: throws ProducerException {
067: isConnection.addConfigListener(this );
068:
069: //ISConnection.debug.error("ProducerRegistryListener.ProducerRegistryListener(): added listener");
070: }
071:
072: public void globalConfigChanged(String serviceName,
073: String version, String groupName,
074: String serviceComponent, int type) {
075: //ISConnection.debug.error("ProducerRegistryListener.globalConfighanged(): changed, serviceName=" + serviceName);
076: clearProducerRegistry();
077: }
078:
079: public void clearProducerRegistry() {
080: producerRegistry = null;
081: ProducerRegistryManager.this .producerRegistry = null;
082: }
083:
084: public void organizationConfigChanged(String serviceName,
085: String version, String orgName, String groupName,
086: String serviceComponent, int type) {
087: // nothing
088: }
089:
090: public void schemaChanged(String serviceName, String version) {
091: // nothing
092: }
093:
094: public synchronized ProducerRegistry cloneProducerRegistry(
095: ProducerJAXB producerJAXB) throws ProducerException {
096: ProducerRegistry pr = null;
097:
098: try {
099: pr = producerJAXB.getObjectFactory()
100: .createProducerRegistry();
101: } catch (JAXBException je) {
102: throw new ProducerException(je);
103: }
104:
105: for (Iterator i = getProducerRegistry(producerJAXB)
106: .getProducerRegistryElement().iterator(); i
107: .hasNext();) {
108: ProducerRegistryElement pre = (ProducerRegistryElement) i
109: .next();
110: pr.getProducerRegistryElement().add(pre);
111: }
112:
113: return pr;
114: }
115:
116: private ProducerRegistry getProducerRegistry(
117: ProducerJAXB producerJAXB) throws ProducerException {
118: if (producerRegistry == null) {
119: if (logger.isLoggable(Level.FINEST))
120: logger.log(Level.FINEST, "PSWS_CSPWSP0001");
121:
122: String registryXML = isConnection
123: .getGlobalStringAttribute(ATTR_PRODUCER_REGISTRY);
124: //ISConnection.debug.error("ProducerRegistryListener.getProducerRegistry(): got registryXML=" + registryXML);
125:
126: if (registryXML != null && registryXML.length() > 0) {
127: //ISConnection.debug.error("ProducerRegistryListener.getProducerRegistry(): registryXML was not null");
128: InputStream is = null;
129: try {
130: is = new ByteArrayInputStream(registryXML
131: .getBytes("UTF-8"));
132: } catch (UnsupportedEncodingException uee) {
133: throw new ProducerException(uee);
134: }
135:
136: try {
137: producerRegistry = (ProducerRegistry) producerJAXB
138: .getUnmarshaller().unmarshal(is);
139: } catch (JAXBException je) {
140: throw new ProducerException(
141: "could not unmarshal producer registry",
142: je);
143: }
144: } else {
145: //ISConnection.debug.error("ProducerRegistryListener.getProducerRegistry(): registryXML was null");
146: try {
147: producerRegistry = producerJAXB
148: .getObjectFactory()
149: .createProducerRegistry();
150: } catch (JAXBException je) {
151: throw new ProducerException(
152: "could not create new producer registry",
153: je);
154: }
155: }
156: } else {
157: if (logger.isLoggable(Level.FINEST))
158: logger.log(Level.FINEST, "PSWS_CSPWSP0002");
159: }
160:
161: return producerRegistry;
162: }
163: }
164:
165: private ProducerRegistryManager() throws ProducerException {
166: // nothing, cannot be called
167: }
168:
169: private ProducerRegistryManager(SSOToken token, String portalId)
170: throws ProducerException {
171: this .token = token;
172: this .portalId = portalId;
173: isConnection = new ISConnection(token, portalId);
174: producerJAXB = new ProducerJAXB();
175: try {
176: producerRegistryListener = new ProducerRegistryListener(
177: portalId);
178: } catch (ProducerException pe) {
179: throw new ProducerError(pe);
180: }
181:
182: }
183:
184: private ProducerRegistryManager(SSOToken token)
185: throws ProducerException {
186: this .token = token;
187: isConnection = new ISConnection(token);
188: producerJAXB = new ProducerJAXB();
189: try {
190: producerRegistryListener = new ProducerRegistryListener();
191: } catch (ProducerException pe) {
192: throw new ProducerError(pe);
193: }
194:
195: }
196:
197: private ProducerRegistry getProducerRegistry()
198: throws ProducerException {
199: if (producerRegistry == null) {
200: producerRegistry = producerRegistryListener
201: .cloneProducerRegistry(producerJAXB);
202: }
203:
204: return producerRegistry;
205: }
206:
207: public Set getKeys() throws ProducerException {
208: Set keys = new HashSet();
209: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
210: ProducerRegistryElement e = (ProducerRegistryElement) i
211: .next();
212: keys.add(e.getKey());
213: }
214:
215: return keys;
216: }
217:
218: public Set getKeys(String org) throws ProducerException {
219: Set keys = new HashSet();
220: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
221: ProducerRegistryElement e = (ProducerRegistryElement) i
222: .next();
223: if (e.getOrganization().equals(org)) {
224: keys.add(e.getKey());
225: }
226: }
227:
228: return keys;
229: }
230:
231: public String getKey(String org, String instance)
232: throws ProducerException {
233: String key = null;
234:
235: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
236: ProducerRegistryElement e = (ProducerRegistryElement) i
237: .next();
238: if (e.getOrganization().equals(org)
239: && e.getInstance().equals(instance)) {
240: key = e.getKey();
241: break;
242: }
243: }
244:
245: return key;
246: }
247:
248: public String getOrganization(String key) throws ProducerException {
249: String org = null;
250:
251: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
252: ProducerRegistryElement e = (ProducerRegistryElement) i
253: .next();
254: if (e.getKey().equals(key)) {
255: org = e.getOrganization();
256: break;
257: }
258: }
259:
260: return org;
261: }
262:
263: public String getInstance(String key) throws ProducerException {
264: String instance = null;
265:
266: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
267: ProducerRegistryElement e = (ProducerRegistryElement) i
268: .next();
269: if (e.getKey().equals(key)) {
270: instance = e.getInstance();
271: break;
272: }
273: }
274:
275: return instance;
276: }
277:
278: public boolean keyExists(String key) throws ProducerException {
279: boolean exists = false;
280:
281: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
282: ProducerRegistryElement e = (ProducerRegistryElement) i
283: .next();
284: if (e.getKey().equals(key)) {
285: exists = true;
286: break;
287: }
288: }
289:
290: return exists;
291: }
292:
293: public void remove(String key) throws ProducerException {
294: ProducerRegistryElement remove = null;
295:
296: for (Iterator i = getProducerRegistryElements(); i.hasNext();) {
297: ProducerRegistryElement e = (ProducerRegistryElement) i
298: .next();
299: if (e.getKey().equals(key)) {
300: remove = e;
301: break;
302: }
303: }
304:
305: //
306: // if remove == null, that means we did not
307: // find the item to be removed
308: //
309:
310: if (remove != null) {
311: getProducerRegistry().getProducerRegistryElement().remove(
312: remove);
313: }
314:
315: store();
316: }
317:
318: public void add(String key, String organization, String instance)
319: throws ProducerException {
320: if (keyExists(key)) {
321: throw new ProducerException("already exists key=" + key);
322: }
323:
324: ProducerRegistryElement e = null;
325: try {
326: e = producerJAXB.getObjectFactory()
327: .createProducerRegistryElement();
328: } catch (JAXBException je) {
329: throw new ProducerException(je);
330: }
331:
332: e.setKey(key);
333: e.setOrganization(organization);
334: e.setInstance(instance);
335:
336: getProducerRegistry().getProducerRegistryElement().add(e);
337:
338: store();
339: }
340:
341: private boolean isValidRegistryElement(ProducerRegistryElement e)
342: throws ProducerException {
343: String org = e.getOrganization();
344: String instance = e.getInstance();
345: String producerDN = ProducerDN.getProducerDN(org, instance,
346: portalId);
347: return isConnection.isValidEntry(producerDN);
348: }
349:
350: private Iterator getProducerRegistryElements()
351: throws ProducerException {
352: Iterator i = getProducerRegistry().getProducerRegistryElement()
353: .iterator();
354:
355: //
356: // keep track of (any) invalid registry entries here
357: //
358: List invalidElements = null;
359:
360: //
361: // loop through all of the registry entries. if any of them are
362: // "invalid", then keep track of them for later
363: //
364: while (i.hasNext()) {
365: ProducerRegistryElement e = (ProducerRegistryElement) i
366: .next();
367: if (!isValidRegistryElement(e)) {
368: if (invalidElements == null) {
369: invalidElements = new ArrayList();
370: }
371: invalidElements.add(e);
372: }
373: }
374:
375: if (invalidElements != null) {
376: //
377: // if there's any invalid elements, remove them from the
378: // registry permanently
379: //
380: for (Iterator j = invalidElements.iterator(); j.hasNext();) {
381: ProducerRegistryElement invalidElement = (ProducerRegistryElement) j
382: .next();
383: getProducerRegistry().getProducerRegistryElement()
384: .remove(invalidElement);
385: }
386: store();
387: }
388:
389: //
390: // at this point, if there were any invalid entries
391: // we will have removed them
392: //
393:
394: return getProducerRegistry().getProducerRegistryElement()
395: .iterator();
396: }
397:
398: private void store() throws ProducerException {
399: String s = getXML();
400: isConnection
401: .setGlobalStringAttribute(ATTR_PRODUCER_REGISTRY, s);
402:
403: //
404: // for this instance (jvm), clear out the registry
405: // so we are not waiting on the async notification
406: // before we see the newly added entries
407: //
408: // if another client accesses the registry before
409: // the notification is received, the registry will
410: // be read in, and then cleared when the notification
411: // is received, and then read again upon the next access.
412: // this is an inefficiency that we have accepted.
413: //
414: // note: other instances (jvms) will not see
415: // the new entry until they receive the notification
416: //
417: producerRegistryListener.clearProducerRegistry();
418: }
419:
420: public String getXML() throws ProducerException {
421: ByteArrayOutputStream os = new ByteArrayOutputStream();
422:
423: try {
424: producerJAXB.getMarshaller().marshal(getProducerRegistry(),
425: os);
426: } catch (JAXBException je) {
427: throw new ProducerException(
428: "could not marshal producer registry", je);
429: }
430:
431: String s = null;
432: try {
433: s = os.toString("UTF-8");
434: //ISConnection.debug.error("ProducerRegistryManager.store(): s=" + s);
435: } catch (UnsupportedEncodingException uee) {
436: throw new ProducerException(
437: "could not encode marshalled string s=" + s, uee);
438: }
439:
440: return s;
441: }
442:
443: public static ProducerRegistryManager getRegistryManager()
444: throws ProducerException {
445: SSOToken token = null;
446: if (producerRegistryManager == null) {
447: token = ISConnection.getAdminToken();
448: producerRegistryManager = new ProducerRegistryManager(token);
449: return producerRegistryManager;
450: } else {
451: try {
452: boolean isValid = SSOTokenManager.getInstance()
453: .isValidToken(producerRegistryManager.token);
454: if (isValid) {
455: return producerRegistryManager;
456: } else {
457: token = ISConnection.getAdminToken();
458: producerRegistryManager.isConnection
459: .reinitializeSSOToken(token);
460: return producerRegistryManager;
461: }
462: } catch (SSOException ssoe) {
463: logger.log(Level.SEVERE, "PSWS_CSPWSP0008", ssoe);
464: throw new ProducerException(ssoe.getMessage(), ssoe);
465: }
466: }
467: }
468:
469: public static ProducerRegistryManager getRegistryManager(
470: String portalId) throws ProducerException {
471: ProducerRegistryManager registryManager = (ProducerRegistryManager) registryManagerCache
472: .get(portalId);
473: SSOToken token = null;
474: if (registryManager == null) {
475: token = ISConnection.getAdminToken();
476: registryManager = new ProducerRegistryManager(token,
477: portalId);
478: registryManagerCache.put(portalId, registryManager);
479: return registryManager;
480: } else {
481: try {
482: boolean isValid = SSOTokenManager.getInstance()
483: .isValidToken(registryManager.token);
484: if (isValid) {
485: return registryManager;
486: } else {
487: token = ISConnection.getAdminToken();
488: registryManager.isConnection
489: .reinitializeSSOToken(token);
490: return registryManager;
491: }
492: } catch (SSOException ssoe) {
493: logger.log(Level.SEVERE, "PSWS_CSPWSP0008", ssoe);
494: throw new ProducerException(ssoe.getMessage(), ssoe);
495: }
496: }
497: }
498: }
|