/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. * */ // SLPTemplateRegistry.java: Service object for registering a new service // template. // Author: James Kempf // Created On: Tue May 27 15:04:35 1997 // Last Modified By: James Kempf // Last Modified On: Thu Jan 7 14:25:20 1999 // Update Count: 134 // package com.sun.slp; import java.util.*; /** * The SLPTemplateRegistry class registers and unregisters service templates, * looks up the template based on the service type name, and returns an * attribute verifier for the service.It subclasses the TemplateRegistry * abstract class. * * An slp-template URL has the following format: * * service:slp-template:;type=; * version=; * language= * * @author James Kempf * */ class SLPTemplateRegistry extends TemplateRegistry { /** * Attribute id for attribute describing service type name. * String, single valued attribute. */ static final String SERVICE_ATTR_ID = "template-type"; /** * Attribute id for attribute describing help text. * String, single valued, required attribute, . */ static final String DESCRIPTION_ATTR_ID = "template-description"; /** * Attribute id for attribute describing service version. The * version number is of the form ``n.m'', where n and m are integers. * String, single valued, required attribute. */ static final String VERSION_ATTR_ID = "template-version"; /** * Attribute id for attribute describing service URL url part grammer. * String, single valued, required attribute. */ static final String SERVICE_URL_ATTR_ID = "template-url-syntax"; /** * The service type name for the template type. */ static final String TEMPLATE_SERVICE_TYPE = "service:slp-template"; // The distinguished template registry object. private static TemplateRegistry registry = null; // Package private constructor for singleton pattern maintained // by the ServiceLocationManager. SLPTemplateRegistry() throws ServiceLocationException { } // // Public implementation. // /** * Register the new service. * * @param serviceType Name of the service. * @param documentURL URL of the template document. * @param languageLocale Locale of the template langugae. * @param version Version number of template document. * @exception ServiceLocationException Error code is * INVALID_REGISTRATION * if the service already exists or * the registration fails. * Throws * SYSTEM_ERROR * if the scope vector is null or * empty. * Throws * PARSE_ERROR * if an attribute is bad. * @exception IllegalArgumentException Thrown if any parameters are null. * */ public void registerServiceTemplate(ServiceType serviceType, String documentURL, Locale languageLocale, String version) throws ServiceLocationException { // Check for illegal parameters. Assert.nonNullParameter(serviceType, "serviceType"); Assert.nonNullParameter(documentURL, "documentURL"); Assert.nonNullParameter(languageLocale, "language"); Assert.nonNullParameter(version, "version"); String language = languageLocale.getLanguage(); if (language == null || language.length() <= 0) { throw new IllegalArgumentException( SLPConfig.getSLPConfig().formatMessage("template_lang_null", new Object[] { documentURL})); } String turl = null; try { turl = findTemplateURL(serviceType, languageLocale, version); } catch (ServiceLocationException ex) { // Ignore if language not supported, it just means there // isn't any. if (ex.getErrorCode() != ServiceLocationException.LANGUAGE_NOT_SUPPORTED) { throw ex; } } // Throw an exception if it exists. if (turl != null) { throw new ServiceLocationException( ServiceLocationException.INVALID_REGISTRATION, "template_already_registered", new Object[] { documentURL, version, languageLocale}); } // Construct attributes for the registration. Vector attributes = new Vector(); // Add the service type name. Vector values = new Vector(); values.addElement(serviceType.toString()); ServiceLocationAttribute attr = new ServiceLocationAttribute(SERVICE_ATTR_ID, values); attributes.addElement(attr); // Add the version. values = new Vector(); values.addElement(version); attr = new ServiceLocationAttribute(VERSION_ATTR_ID, values); attributes.addElement(attr); // Construct a service URL for the template. ServiceURL surl = new ServiceURL(TEMPLATE_SERVICE_TYPE + ":"+ documentURL+ ";"+ SERVICE_ATTR_ID+ "="+ serviceType+ ";"+ VERSION_ATTR_ID+ "="+ version, ServiceURL.LIFETIME_MAXIMUM); // Do the registration. Advertiser serviceAgent = ServiceLocationManager.getAdvertiser(languageLocale); if (serviceAgent == null) { throw new ServiceLocationException( ServiceLocationException.NOT_IMPLEMENTED, "no_advertiser", new Object[0]); } serviceAgent.register(surl, attributes); // Note that the assumption here is that the URL containing the // path to the template document is written "somehow". // It is up to the client to make sure that the template document // has been written. } /** * Deregister the template for service type. * * @param serviceType Name of service. * @param languageLocale Language locale of template. * @param version Version of the template, null for latest. * @exception ServiceLocationException Thrown if the deregistration * fails. * @exception IllegalArgumentException Thrown if the parameter is null. * */ public void deregisterServiceTemplate(ServiceType serviceType, Locale languageLocale, String version) throws ServiceLocationException { // Check the parameter. Assert.nonNullParameter(serviceType, "serviceType"); Assert.nonNullParameter(languageLocale, "languageLocale"); // Get the template document URL for the service. ServiceURL turl = findVersionedURL(serviceType, languageLocale, version); // If there's no template, then throw an exception. if (turl == null) { throw new ServiceLocationException( ServiceLocationException.INVALID_REGISTRATION, "template_not_registered", new Object[] { serviceType, version, languageLocale}); } // Deregister in all scopes. Advertiser serviceAgent = ServiceLocationManager.getAdvertiser(languageLocale); if (serviceAgent == null) { throw new ServiceLocationException( ServiceLocationException.NOT_IMPLEMENTED, "no_advertiser", new Object[0]); } // Deregister the service URL. serviceAgent.deregister(turl); } /** * Find the service URL for the service. * * @param serviceType Name of service. * @param languageLocale Language locale of template. * @param version Version of the template, null for latest. * @return ServiceURL for the service template. If the service doesn't * exist, returns null. * @exception ServiceLocationException Error code is * SYSTEM_ERROR * if the scope vector is null or * empty or if more than one * template URL is returned. * @exception IllegalArgumentException Thrown if any parameters are null. * */ public String findTemplateURL(ServiceType serviceType, Locale languageLocale, String version) throws ServiceLocationException { // Check the parameter. Assert.nonNullParameter(serviceType, "serviceType"); Assert.nonNullParameter(languageLocale, "languageLocale"); ServiceURL turl = findVersionedURL(serviceType, languageLocale, version); // If nothing returned, then simply return. if (turl == null) { return null; } // Form the document URL. ServiceType type = turl.getServiceType(); String url = turl.toString(); String abstractType = type.getAbstractTypeName(); if (!abstractType.equals(TEMPLATE_SERVICE_TYPE)) { throw new ServiceLocationException( ServiceLocationException.PARSE_ERROR, "template_url_malformed", new Object[] {turl}); } // Parse off the URL path. int idx = url.indexOf(";"+SERVICE_ATTR_ID+"="); if (idx == -1) { throw new ServiceLocationException( ServiceLocationException.PARSE_ERROR, "template_url_malformed", new Object[] {turl}); } int jdx = TEMPLATE_SERVICE_TYPE.length() + 1; // don't forget :!!! // Return the document URL. return url.substring(jdx, idx); } // Return a URL given a version and language locale. private ServiceURL findVersionedURL(ServiceType serviceType, Locale languageLocale, String version) throws ServiceLocationException { // Templates should be registered in all scopes. Look for them // in all. Vector scopes = ServiceLocationManager.findScopes(); // Set up query. ServiceLocationEnumeration results = null; String query = "(" + SERVICE_ATTR_ID + "=" + serviceType + ")"; if (version != null) { query = query + "(" + VERSION_ATTR_ID + "=" + version + ")"; } query = "(&" + query + ")"; // Get user agent for query. Locator userAgent = ServiceLocationManager.getLocator(languageLocale); if (userAgent == null) { throw new ServiceLocationException( ServiceLocationException.NOT_IMPLEMENTED, "no_locator", new Object[0]); } try { ServiceType type = new ServiceType(TEMPLATE_SERVICE_TYPE); results = userAgent.findServices(type, scopes, query); } catch (ServiceLocationException ex) { // If language not supported, it just means none there. if (ex.getErrorCode() != ServiceLocationException.LANGUAGE_NOT_SUPPORTED) { throw ex; } } // If nothing came back, then return null. if (!results.hasMoreElements()) { return null; } ServiceURL turl = null; float highest = (float)-1.0; // If there's more than one service of this type registered, then // take highest version if version number was null. while (results.hasMoreElements()) { ServiceURL surl = (ServiceURL)results.nextElement(); String urlPath = surl.getURLPath(); if (version == null) { // Get the version attribute from the URL. String token = ";"+VERSION_ATTR_ID+"="; int idx = urlPath.indexOf(token); if (idx == -1) { // ignore, there may be more... continue; } urlPath = urlPath.substring(idx+token.length(), urlPath.length()); idx = urlPath.indexOf(";"); if (idx == -1) { // ignore, there may be more... continue; } String temversion = urlPath.substring(0, idx); float current = (float)0.0; // Convert to float. try { current = Float.valueOf(temversion).floatValue(); } catch (NumberFormatException ex) { continue; // ignore, there may be more... } // Identify if this is the highest version number so far. if (current > highest) { turl = surl; } } else { // If we found more than one, may be a problem. if (turl != null) { throw new ServiceLocationException( ServiceLocationException.INTERNAL_SYSTEM_ERROR, "template_multiple", new Object[] { serviceType, version, languageLocale}); } turl = surl; } } return turl; } /** * Create an attribute verifier for the template document URL. * * @param documentURL A URL for the template document URL. * @return An attribute verifier for the service * @exception ServiceLocationException Throws * PARSE_ERROR * if any syntax errors * are encountered during parsing * of service's template definition. * Throws * SYSTEM_ERROR * if URL parsing error occurs. * Throws ServiceLocationException * if any other errors occur. * @exception IllegalArgumentException Thrown if any parameters are null. * */ public ServiceLocationAttributeVerifier attributeVerifier( String documentURL) throws ServiceLocationException { // Check the parameter. Assert.nonNullParameter(documentURL, "documentURL"); // Create a URL attribute parser to parse the document. return new URLAttributeVerifier(documentURL); } }