/** * * Copyright 2003-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.console.databasemanager.wizard; import java.io.IOException; import java.io.Serializable; import java.io.PrintWriter; import java.io.StringWriter; import java.io.File; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.StringReader; import java.io.ByteArrayOutputStream; import java.io.FileReader; import java.util.Map; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.Collections; import java.util.Properties; import java.net.URISyntaxException; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.net.MalformedURLException; import java.sql.Driver; import java.sql.SQLException; import java.sql.Connection; import java.sql.DatabaseMetaData; import javax.portlet.PortletRequestDispatcher; import javax.portlet.PortletConfig; import javax.portlet.PortletException; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.portlet.WindowState; import javax.portlet.PortletRequest; import javax.portlet.PortletSession; import javax.management.ObjectName; import javax.management.MalformedObjectNameException; import javax.enterprise.deploy.spi.DeploymentManager; import javax.enterprise.deploy.spi.DeploymentConfiguration; import javax.enterprise.deploy.spi.Target; import javax.enterprise.deploy.spi.TargetModuleID; import javax.enterprise.deploy.spi.status.ProgressObject; import javax.enterprise.deploy.model.DDBeanRoot; import javax.enterprise.deploy.model.DDBean; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.apache.geronimo.console.BasePortlet; import org.apache.geronimo.console.GeronimoVersion; import org.apache.geronimo.console.util.PortletManager; import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory; import org.apache.geronimo.management.geronimo.ResourceAdapterModule; import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; import org.apache.geronimo.kernel.repository.ListableRepository; import org.apache.geronimo.kernel.repository.Repository; import org.apache.geronimo.kernel.repository.WriteableRepository; import org.apache.geronimo.kernel.repository.FileWriteMonitor; import org.apache.geronimo.kernel.management.State; import org.apache.geronimo.kernel.proxy.GeronimoManagedBean; import org.apache.geronimo.deployment.tools.loader.ConnectorDeployable; import org.apache.geronimo.connector.deployment.jsr88.Connector15DCBRoot; import org.apache.geronimo.connector.deployment.jsr88.ConnectorDCB; import org.apache.geronimo.connector.deployment.jsr88.Dependency; import org.apache.geronimo.connector.deployment.jsr88.ResourceAdapter; import org.apache.geronimo.connector.deployment.jsr88.ConnectionDefinition; import org.apache.geronimo.connector.deployment.jsr88.ConnectionDefinitionInstance; import org.apache.geronimo.connector.deployment.jsr88.ConfigPropertySetting; import org.apache.geronimo.connector.deployment.jsr88.ConnectionManager; import org.apache.geronimo.connector.deployment.jsr88.SinglePool; import org.apache.geronimo.connector.outbound.PoolingAttributes; import org.apache.geronimo.converter.DatabaseConversionStatus; import org.apache.geronimo.converter.JDBCPool; import org.apache.geronimo.converter.bea.WebLogic81DatabaseConverter; import org.apache.geronimo.converter.jboss.JBoss4DatabaseConverter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.fileupload.portlet.PortletFileUpload; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.FileItem; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.xml.sax.InputSource; /** * A portlet that lets you configure and deploy JDBC connection pools. * * @version $Rev$ $Date$ */ public class DatabasePoolPortlet extends BasePortlet { private final static Log log = LogFactory.getLog(DatabasePoolPortlet.class); private final static String[] SKIP_ENTRIES_WITH = new String[]{"geronimo", "tomcat", "tranql", "commons", "directory", "activemq"}; private final static String DRIVER_SESSION_KEY = "org.apache.geronimo.console.dbpool.Drivers"; private final static String CONFIG_SESSION_KEY = "org.apache.geronimo.console.dbpool.ConfigParam"; private final static String DRIVER_INFO_URL = "http://people.apache.org/~ammulder/driver-downloads.properties"; private static final String LIST_VIEW = "/WEB-INF/view/dbwizard/list.jsp"; private static final String EDIT_VIEW = "/WEB-INF/view/dbwizard/edit.jsp"; private static final String SELECT_RDBMS_VIEW = "/WEB-INF/view/dbwizard/selectDatabase.jsp"; private static final String BASIC_PARAMS_VIEW = "/WEB-INF/view/dbwizard/basicParams.jsp"; private static final String CONFIRM_URL_VIEW = "/WEB-INF/view/dbwizard/confirmURL.jsp"; private static final String TEST_CONNECTION_VIEW = "/WEB-INF/view/dbwizard/testConnection.jsp"; private static final String DOWNLOAD_VIEW = "/WEB-INF/view/dbwizard/selectDownload.jsp"; private static final String SHOW_PLAN_VIEW = "/WEB-INF/view/dbwizard/showPlan.jsp"; private static final String IMPORT_UPLOAD_VIEW = "/WEB-INF/view/dbwizard/importUpload.jsp"; private static final String IMPORT_STATUS_VIEW = "/WEB-INF/view/dbwizard/importStatus.jsp"; private static final String USAGE_VIEW = "/WEB-INF/view/dbwizard/usage.jsp"; private static final String LIST_MODE = "list"; private static final String EDIT_MODE = "edit"; private static final String SELECT_RDBMS_MODE = "rdbms"; private static final String BASIC_PARAMS_MODE = "params"; private static final String CONFIRM_URL_MODE = "url"; private static final String TEST_CONNECTION_MODE = "test"; private static final String SHOW_PLAN_MODE = "plan"; private static final String DOWNLOAD_MODE = "download"; private static final String EDIT_EXISTING_MODE = "editExisting"; private static final String SAVE_MODE = "save"; private static final String IMPORT_START_MODE = "startImport"; private static final String IMPORT_UPLOAD_MODE = "importUpload"; private static final String IMPORT_STATUS_MODE = "importStatus"; private static final String IMPORT_COMPLETE_MODE = "importComplete"; private static final String WEBLOGIC_IMPORT_MODE = "weblogicImport"; private static final String USAGE_MODE = "usage"; private static final String IMPORT_EDIT_MODE = "importEdit"; private static final String MODE_KEY = "mode"; private PortletRequestDispatcher listView; private PortletRequestDispatcher editView; private PortletRequestDispatcher selectRDBMSView; private PortletRequestDispatcher basicParamsView; private PortletRequestDispatcher confirmURLView; private PortletRequestDispatcher testConnectionView; private PortletRequestDispatcher downloadView; private PortletRequestDispatcher planView; private PortletRequestDispatcher importUploadView; private PortletRequestDispatcher importStatusView; private PortletRequestDispatcher usageView; public void init(PortletConfig portletConfig) throws PortletException { super.init(portletConfig); listView = portletConfig.getPortletContext().getRequestDispatcher(LIST_VIEW); editView = portletConfig.getPortletContext().getRequestDispatcher(EDIT_VIEW); selectRDBMSView = portletConfig.getPortletContext().getRequestDispatcher(SELECT_RDBMS_VIEW); basicParamsView = portletConfig.getPortletContext().getRequestDispatcher(BASIC_PARAMS_VIEW); confirmURLView = portletConfig.getPortletContext().getRequestDispatcher(CONFIRM_URL_VIEW); testConnectionView = portletConfig.getPortletContext().getRequestDispatcher(TEST_CONNECTION_VIEW); downloadView = portletConfig.getPortletContext().getRequestDispatcher(DOWNLOAD_VIEW); planView = portletConfig.getPortletContext().getRequestDispatcher(SHOW_PLAN_VIEW); importUploadView = portletConfig.getPortletContext().getRequestDispatcher(IMPORT_UPLOAD_VIEW); importStatusView = portletConfig.getPortletContext().getRequestDispatcher(IMPORT_STATUS_VIEW); usageView = portletConfig.getPortletContext().getRequestDispatcher(USAGE_VIEW); } public void destroy() { listView = null; editView = null; selectRDBMSView = null; basicParamsView = null; confirmURLView = null; testConnectionView = null; downloadView = null; planView = null; importUploadView = null; importStatusView = null; usageView = null; super.destroy(); } public DriverDownloader.DriverInfo[] getDriverInfo(PortletRequest request) { PortletSession session = request.getPortletSession(true); DriverDownloader.DriverInfo[] results = (DriverDownloader.DriverInfo[]) session.getAttribute(DRIVER_SESSION_KEY, PortletSession.APPLICATION_SCOPE); if(results == null) { DriverDownloader downloader = new DriverDownloader(); try { results = downloader.loadDriverInfo(new URL(DRIVER_INFO_URL)); session.setAttribute(DRIVER_SESSION_KEY, results, PortletSession.APPLICATION_SCOPE); } catch (MalformedURLException e) { log.error("Unable to download driver data", e); results = new DriverDownloader.DriverInfo[0]; } } return results; } /** * Loads data about a resource adapter. Depending on what we already have, may load * the name and description, but always loads the config property descriptions. * @param request Pass it or die * @param rarPath If we're creating a new RA, the path to identify it * @param displayName If we're editing an existing RA, its name * @param adapterObjectName If we're editing an existing RA, its ObjectName */ public ResourceAdapterParams getRARConfiguration(PortletRequest request, String rarPath, String displayName, String adapterObjectName) { PortletSession session = request.getPortletSession(true); if(rarPath != null && !rarPath.equals("")) { ResourceAdapterParams results = (ResourceAdapterParams) session.getAttribute(CONFIG_SESSION_KEY+"-"+rarPath, PortletSession.APPLICATION_SCOPE); if(results == null) { results = loadConfigPropertiesByPath(request, rarPath); session.setAttribute(CONFIG_SESSION_KEY+"-"+rarPath, results, PortletSession.APPLICATION_SCOPE); session.setAttribute(CONFIG_SESSION_KEY+"-"+results.displayName, results, PortletSession.APPLICATION_SCOPE); } return results; } else if(displayName != null && !displayName.equals("") && adapterObjectName != null && !adapterObjectName.equals("")) { ResourceAdapterParams results = (ResourceAdapterParams) session.getAttribute(CONFIG_SESSION_KEY+"-"+displayName, PortletSession.APPLICATION_SCOPE); if(results == null) { results = loadConfigPropertiesByObjectName(request, adapterObjectName); session.setAttribute(CONFIG_SESSION_KEY+"-"+displayName, results, PortletSession.APPLICATION_SCOPE); } return results; } else { throw new IllegalArgumentException(); } } public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException { String mode = actionRequest.getParameter(MODE_KEY); if(mode.equals(IMPORT_UPLOAD_MODE)) { processImportUpload(actionRequest, actionResponse); actionResponse.setRenderParameter(MODE_KEY, IMPORT_STATUS_MODE); return; } PoolData data = new PoolData(); data.load(actionRequest); if(mode.equals("process-"+SELECT_RDBMS_MODE)) { DatabaseInfo info = null; info = getDatabaseInfo(data); if(info != null) { data.rarPath = info.getRarPath(); if(info.isXA()) { data.adapterDisplayName="Unknown"; // will pick these up when we process the RA type in the render request data.adapterDescription="Unknown"; actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); } else { if(data.getDbtype().equals("Other")) { actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); } else { data.driverClass = info.getDriverClass(); data.urlPrototype = info.getUrl(); actionResponse.setRenderParameter(MODE_KEY, BASIC_PARAMS_MODE); } } } else { actionResponse.setRenderParameter(MODE_KEY, SELECT_RDBMS_MODE); } } else if(mode.equals("process-"+DOWNLOAD_MODE)) { String name = actionRequest.getParameter("driverName"); DriverDownloader.DriverInfo[] drivers = getDriverInfo(actionRequest); DriverDownloader.DriverInfo found = null; for (int i = 0; i < drivers.length; i++) { DriverDownloader.DriverInfo driver = drivers[i]; if(driver.getName().equals(name)) { found = driver; break; } } if(found != null) { DriverDownloader downloader = new DriverDownloader(); WriteableRepository repo = PortletManager.getWritableRepositories(actionRequest)[0]; try { downloader.loadDriver(repo, found, new FileWriteMonitor() { public void writeStarted(String fileDescription) { System.out.println("Downloading "+fileDescription); } public void writeProgress(int bytes) { System.out.print("\rDownload progress: "+(bytes/1024)+"kB"); System.out.flush(); } public void writeComplete(int bytes) { System.out.println(); System.out.println("Finished downloading "+bytes+"b"); } }); data.jar1 = found.getRepositoryURI(); } catch (IOException e) { log.error("Unable to download JDBC driver", e); } } if(data.getDbtype() == null || data.getDbtype().equals("Other")) { actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); } else { actionResponse.setRenderParameter(MODE_KEY, BASIC_PARAMS_MODE); } } else if(mode.equals("process-"+BASIC_PARAMS_MODE)) { DatabaseInfo info = null; info = getDatabaseInfo(data); if(info != null) { data.url = populateURL(info.getUrl(), info.getUrlParameters(), data.getUrlProperties()); } if(attemptDriverLoad(actionRequest, data) != null) { actionResponse.setRenderParameter(MODE_KEY, CONFIRM_URL_MODE); } else { actionResponse.setRenderParameter("driverError", "Unable to load driver "+data.driverClass); actionResponse.setRenderParameter(MODE_KEY, BASIC_PARAMS_MODE); } } else if(mode.equals("process-"+CONFIRM_URL_MODE)) { String test = actionRequest.getParameter("test"); if(test == null || test.equals("true")) { String result = null; String stack = null; try { result = attemptConnect(actionRequest, data); } catch (Exception e) { StringWriter writer = new StringWriter(); PrintWriter temp = new PrintWriter(writer); e.printStackTrace(temp); temp.flush(); temp.close(); stack = writer.getBuffer().toString(); } if(result != null) actionResponse.setRenderParameter("connectResult", result); actionRequest.getPortletSession(true).setAttribute("connectError", stack); actionResponse.setRenderParameter(MODE_KEY, TEST_CONNECTION_MODE); } else { save(actionRequest, actionResponse, data, false); } } else if(mode.equals(SAVE_MODE)) { save(actionRequest, actionResponse, data, false); } else if(mode.equals(SHOW_PLAN_MODE)) { String plan = save(actionRequest, actionResponse, data, true); actionRequest.getPortletSession(true).setAttribute("deploymentPlan", plan); actionResponse.setRenderParameter(MODE_KEY, SHOW_PLAN_MODE); } else if(mode.equals(EDIT_EXISTING_MODE)) { final String name = actionRequest.getParameter("adapterObjectName"); loadConnectionFactory(actionRequest, name, data.getObjectName(), data); actionResponse.setRenderParameter("adapterObjectName", name); actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); } else if(mode.equals(SELECT_RDBMS_MODE)) { if(data.getAdapterDisplayName() == null) { // Set a default for a new pool data.adapterDisplayName = "TranQL Generic JDBC Resource Adapter"; } actionResponse.setRenderParameter(MODE_KEY, mode); } else if(mode.equals(WEBLOGIC_IMPORT_MODE)) { String domainDir = actionRequest.getParameter("weblogicDomainDir"); String libDir = actionRequest.getParameter("weblogicLibDir"); try { DatabaseConversionStatus status = WebLogic81DatabaseConverter.convert(libDir, domainDir); actionRequest.getPortletSession(true).setAttribute("ImportStatus", new ImportStatus(status)); actionResponse.setRenderParameter(MODE_KEY, IMPORT_STATUS_MODE); } catch (Exception e) { log.error("Unable to import", e); actionResponse.setRenderParameter("from", actionRequest.getParameter("from")); actionResponse.setRenderParameter(MODE_KEY, IMPORT_START_MODE); } } else if(mode.equals(IMPORT_START_MODE)) { actionResponse.setRenderParameter("from", actionRequest.getParameter("from")); actionResponse.setRenderParameter(MODE_KEY, mode); } else if(mode.equals(IMPORT_EDIT_MODE)) { ImportStatus status = getImportStatus(actionRequest); int index = Integer.parseInt(actionRequest.getParameter("importIndex")); status.setCurrentPoolIndex(index); loadImportedData(data, status.getCurrentPool()); actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE); } else if(mode.equals(IMPORT_COMPLETE_MODE)) { ImportStatus status = getImportStatus(actionRequest); log.warn("Import Results:"); //todo: create a screen for this log.warn(" "+status.getSkippedCount()+" ignored"); log.warn(" "+status.getStartedCount()+" reviewed but not deployed"); log.warn(" "+status.getPendingCount()+" not reviewed"); log.warn(" "+status.getFinishedCount()+" deployed"); actionRequest.getPortletSession().removeAttribute("ImportStatus"); } else { actionResponse.setRenderParameter(MODE_KEY, mode); } data.store(actionResponse); } private void loadImportedData(PoolData data, ImportStatus.PoolProgress progress) { if(!progress.getType().equals(ImportStatus.PoolProgress.TYPE_XA)) { JDBCPool pool = (JDBCPool) progress.getPool(); data.dbtype = "Other"; data.adapterDisplayName = "TranQL Generic JDBC Resource Adapter"; data.blockingTimeout = getImportString(pool.getBlockingTimeoutMillis()); data.driverClass = pool.getDriverClass(); data.idleTimeout = pool.getIdleTimeoutMillis() == null ? null : Integer.toString(pool.getIdleTimeoutMillis().intValue() / (60 * 1000)); data.maxSize = getImportString(pool.getMaxSize()); data.minSize = getImportString(pool.getMinSize()); data.name = pool.getName(); data.password = pool.getPassword(); data.url = pool.getJdbcURL(); data.user = pool.getUsername(); if(pool.getDriverClass() != null) { DatabaseInfo info = getDatabaseInfoFromDriver(data); if(info != null) { data.rarPath = info.getRarPath(); data.urlPrototype = info.getUrl(); } else { log.warn("Don't recognize database driver "+data.driverClass+"; Using default RAR file"); data.rarPath = DatabaseInfo.getDefaultRARPath(); } } } else { //todo: handle XA } } private static String getImportString(Integer value) { return value == null ? null : value.toString(); } private boolean processImportUpload(ActionRequest request, ActionResponse response) throws PortletException { String type = request.getParameter("importSource"); response.setRenderParameter("importSource", type); if (!PortletFileUpload.isMultipartContent(request)) { throw new PortletException("Expected file upload"); } PortletFileUpload uploader = new PortletFileUpload(new DiskFileItemFactory()); try { List items = uploader.parseRequest(request); for (Iterator i = items.iterator(); i.hasNext();) { FileItem item = (FileItem) i.next(); if (!item.isFormField()) { File file = File.createTempFile("geronimo-import", ""); file.deleteOnExit(); log.debug("Writing database pool import file to "+file.getAbsolutePath()); item.write(file); DatabaseConversionStatus status = processImport(file, type); request.getPortletSession(true).setAttribute("ImportStatus", new ImportStatus(status)); return true; } else { throw new PortletException("Not expecting any form fields"); } } } catch(PortletException e) { throw e; } catch(Exception e) { throw new PortletException(e); } return false; } private DatabaseConversionStatus processImport(File importFile, String type) throws PortletException, IOException { if(type.equals("JBoss 4")) { return JBoss4DatabaseConverter.convert(new FileReader(importFile)); } else if(type.equals("WebLogic 8.1")) { return WebLogic81DatabaseConverter.convert(new FileReader(importFile)); } else { throw new PortletException("Unknown import type '"+type+"'"); } } private ResourceAdapterParams loadConfigPropertiesByPath(PortletRequest request, String rarPath) { DeploymentManager mgr = PortletManager.getDeploymentManager(request); try { URL url = getRAR(request, rarPath); ConnectorDeployable deployable = new ConnectorDeployable(url); final DDBeanRoot ddBeanRoot = deployable.getDDBeanRoot(); String adapterName = null, adapterDesc = null; String[] test = ddBeanRoot.getText("connector/display-name"); if(test != null && test.length > 0) { adapterName = test[0]; } test = ddBeanRoot.getText("connector/description"); if(test != null && test.length > 0) { adapterDesc = test[0]; } DDBean[] definitions = ddBeanRoot.getChildBean("connector/resourceadapter/outbound-resourceadapter/connection-definition"); List configs = new ArrayList(); if(definitions != null) { for (int i = 0; i < definitions.length; i++) { DDBean definition = definitions[i]; String iface = definition.getText("connectionfactory-interface")[0]; if(iface.equals("javax.sql.DataSource")) { DDBean[] beans = definition.getChildBean("config-property"); for (int j = 0; j < beans.length; j++) { DDBean bean = beans[j]; String name = bean.getText("config-property-name")[0].trim(); String type = bean.getText("config-property-type")[0].trim(); test = bean.getText("config-property-value"); String value = test == null || test.length == 0 ? null : test[0].trim(); test = bean.getText("description"); String desc = test == null || test.length == 0 ? null : test[0].trim(); configs.add(new ConfigParam(name, type, desc, value)); } } } } return new ResourceAdapterParams(adapterName, adapterDesc, (ConfigParam[]) configs.toArray(new ConfigParam[configs.size()])); } catch (Exception e) { log.error("Unable to read configuration properties", e); return null; } finally { if(mgr != null) mgr.release(); } } private ResourceAdapterParams loadConfigPropertiesByObjectName(PortletRequest request, String objectName) { ResourceAdapterModule module = (ResourceAdapterModule) PortletManager.getManagedBean(request, objectName); String dd = module.getDeploymentDescriptor(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setNamespaceAware(true); try { DocumentBuilder builder = factory.newDocumentBuilder(); final StringReader reader = new StringReader(dd); Document doc = builder.parse(new InputSource(reader)); reader.close(); Element elem = doc.getDocumentElement(); // connector String displayName = getFirstText(elem.getElementsByTagName("display-name")); String description = getFirstText(elem.getElementsByTagName("description")); elem = (Element) elem.getElementsByTagName("resourceadapter").item(0); elem = (Element) elem.getElementsByTagName("outbound-resourceadapter").item(0); NodeList defs = elem.getElementsByTagName("connection-definition"); List all = new ArrayList(); for(int i=0; i<defs.getLength(); i++) { final Element def = (Element)defs.item(i); String iface = getFirstText(def.getElementsByTagName("connectionfactory-interface")).trim(); if(iface.equals("javax.sql.DataSource")) { NodeList configs = def.getElementsByTagName("config-property"); for(int j=0; j<configs.getLength(); j++) { Element config = (Element) configs.item(j); String name = getFirstText(config.getElementsByTagName("config-property-name")).trim(); String type = getFirstText(config.getElementsByTagName("config-property-type")).trim(); String test = getFirstText(config.getElementsByTagName("config-property-value")); String value = test == null ? null : test.trim(); test = getFirstText(config.getElementsByTagName("description")); String desc = test == null ? null : test.trim(); all.add(new ConfigParam(name, type, desc, value)); } } } return new ResourceAdapterParams(displayName, description, (ConfigParam[]) all.toArray(new ConfigParam[all.size()])); } catch (Exception e) { log.error("Unable to read resource adapter DD", e); return null; } } private String getFirstText(NodeList list) { if(list.getLength() == 0) { return null; } Element first = (Element) list.item(0); StringBuffer buf = new StringBuffer(); NodeList all = first.getChildNodes(); for(int i=0; i<all.getLength(); i++) { Node node = all.item(i); if(node.getNodeType() == Node.TEXT_NODE) { buf.append(node.getNodeValue()); } } return buf.toString(); } private void loadConnectionFactory(ActionRequest actionRequest, String adapterName, String factoryName, PoolData data) { ResourceAdapterModule adapter = (ResourceAdapterModule) PortletManager.getManagedBean(actionRequest, adapterName); JCAManagedConnectionFactory factory = (JCAManagedConnectionFactory) PortletManager.getManagedBean(actionRequest, factoryName); data.adapterDisplayName = adapter.getDisplayName(); data.adapterDescription = adapter.getDescription(); try { ObjectName oname = ObjectName.getInstance(factoryName); data.name = oname.getKeyProperty("name"); if(data.isGeneric()) { data.url = (String) factory.getConfigProperty("connectionURL"); data.driverClass = (String) factory.getConfigProperty("driver"); data.user = (String) factory.getConfigProperty("userName"); data.password = (String) factory.getConfigProperty("password"); } else { ResourceAdapterParams params = getRARConfiguration(actionRequest, data.getRarPath(), data.getAdapterDisplayName(), adapterName); for(int i=0; i<params.getConfigParams().length; i++) { ConfigParam cp = params.getConfigParams()[i]; Object value = factory.getConfigProperty(cp.getName()); data.properties.put("property-"+cp.getName(), value == null ? null : value.toString()); } } } catch (Exception e) { log.error("Unable to look up connection property", e); } //todo: push the lookup into ManagementHelper PoolingAttributes pool = (PoolingAttributes) PortletManager.getManagedBean(actionRequest, factory.getConnectionManager()); data.minSize = Integer.toString(pool.getPartitionMinSize()); data.maxSize = Integer.toString(pool.getPartitionMaxSize()); data.blockingTimeout = Integer.toString(pool.getBlockingTimeoutMilliseconds()); data.idleTimeout = Integer.toString(pool.getIdleTimeoutMinutes()); } protected void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) { return; } try { String mode = renderRequest.getParameter(MODE_KEY); PoolData data = new PoolData(); data.load(renderRequest); renderRequest.setAttribute("pool", data); // If not headed anywhere in particular, send to list if(mode == null || mode.equals("")) { mode = LIST_MODE; } // If headed to list but there's an import in progress, redirect to import status if(mode.equals(LIST_MODE) && getImportStatus(renderRequest) != null) { mode = IMPORT_STATUS_MODE; } if(mode.equals(LIST_MODE)) { renderList(renderRequest, renderResponse); } else if(mode.equals(EDIT_MODE)) { renderEdit(renderRequest, renderResponse, data); } else if(mode.equals(SELECT_RDBMS_MODE)) { renderSelectRDBMS(renderRequest, renderResponse); } else if(mode.equals(DOWNLOAD_MODE)) { renderDownload(renderRequest, renderResponse); } else if(mode.equals(BASIC_PARAMS_MODE)) { renderBasicParams(renderRequest, renderResponse, data); } else if(mode.equals(CONFIRM_URL_MODE)) { renderConfirmURL(renderRequest, renderResponse); } else if(mode.equals(TEST_CONNECTION_MODE)) { renderTestConnection(renderRequest, renderResponse); } else if(mode.equals(SHOW_PLAN_MODE)) { renderPlan(renderRequest, renderResponse, data); } else if(mode.equals(IMPORT_START_MODE)) { renderImportUploadForm(renderRequest, renderResponse); } else if(mode.equals(IMPORT_STATUS_MODE)) { renderImportStatus(renderRequest, renderResponse); } else if(mode.equals(USAGE_MODE)) { renderUsage(renderRequest, renderResponse); } } catch (Throwable e) { log.error("Unable to render portlet", e); } } private void renderUsage(RenderRequest request, RenderResponse response) throws IOException, PortletException { usageView.include(request, response); } private void renderImportStatus(RenderRequest request, RenderResponse response) throws IOException, PortletException { request.setAttribute("status", getImportStatus(request)); populatePoolList(request); importStatusView.include(request, response); } private void renderImportUploadForm(RenderRequest request, RenderResponse response) throws IOException, PortletException { request.setAttribute("from", request.getParameter("from")); importUploadView.include(request, response); } private void renderList(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { populatePoolList(renderRequest); listView.include(renderRequest, renderResponse); } private void populatePoolList(PortletRequest renderRequest) { ResourceAdapterModule[] modules = PortletManager.getOutboundRAModules(renderRequest, "javax.sql.DataSource"); List list = new ArrayList(); for (int i = 0; i < modules.length; i++) { ResourceAdapterModule module = modules[i]; JCAManagedConnectionFactory[] databases = PortletManager.getOutboundFactoriesForRA(renderRequest, module, "javax.sql.DataSource"); for (int j = 0; j < databases.length; j++) { JCAManagedConnectionFactory db = databases[j]; try { ObjectName name = ObjectName.getInstance(db.getObjectName()); list.add(new ConnectionPool(ObjectName.getInstance(module.getObjectName()), db.getObjectName(), name.getKeyProperty(NameFactory.J2EE_NAME), ((GeronimoManagedBean)db).getState())); } catch (MalformedObjectNameException e) { e.printStackTrace(); } } } Collections.sort(list); renderRequest.setAttribute("pools", list); } private void renderEdit(RenderRequest renderRequest, RenderResponse renderResponse, PoolData data) throws IOException, PortletException { if(data.objectName == null || data.objectName.equals("")) { loadDriverJARList(renderRequest); } if(!data.isGeneric()) { ResourceAdapterParams params = getRARConfiguration(renderRequest, data.getRarPath(), data.getAdapterDisplayName(), renderRequest.getParameter("adapterObjectName")); data.adapterDisplayName = params.getDisplayName(); data.adapterDescription = params.getDescription(); Map map = new HashMap(); boolean more = false; for (int i = 0; i < params.getConfigParams().length; i++) { ConfigParam param = params.getConfigParams()[i]; if(!data.properties.containsKey("property-"+param.getName())) { data.properties.put("property-"+param.getName(), param.getDefaultValue()); more = true; } map.put("property-"+param.getName(), param); } if(more) { data.loadPropertyNames(); } renderRequest.setAttribute("ConfigParams", map); } editView.include(renderRequest, renderResponse); } private void renderSelectRDBMS(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { renderRequest.setAttribute("databases", DatabaseInfo.ALL_DATABASES); selectRDBMSView.include(renderRequest, renderResponse); } private void renderDownload(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { renderRequest.setAttribute("drivers", getDriverInfo(renderRequest)); downloadView.include(renderRequest, renderResponse); } private void renderBasicParams(RenderRequest renderRequest, RenderResponse renderResponse, PoolData data) throws IOException, PortletException { loadDriverJARList(renderRequest); // Make sure all properties available for the DB are listed DatabaseInfo info = getDatabaseInfo(data); if(info != null) { String[] params = info.getUrlParameters(); for (int i = 0; i < params.length; i++) { String param = params[i]; final String key = "urlproperty-"+param; if(!data.getUrlProperties().containsKey(key)) { data.getUrlProperties().put(key, param.equalsIgnoreCase("port") && info.getDefaultPort() > 0 ? new Integer(info.getDefaultPort()) : null); } } } // Pass on errors renderRequest.setAttribute("driverError", renderRequest.getParameter("driverError")); basicParamsView.include(renderRequest, renderResponse); } private void loadDriverJARList(RenderRequest renderRequest) { // List the available JARs List list = new ArrayList(); ListableRepository[] repos = PortletManager.getListableRepositories(renderRequest); for (int i = 0; i < repos.length; i++) { ListableRepository repo = repos[i]; try { final URI[] uris = repo.listURIs(); outer: for (int j = 0; j < uris.length; j++) { if(uris[j] == null) { continue; // probably a JAR lacks a version number in the name, etc. } String test = uris[j].toString(); for (int k = 0; k < SKIP_ENTRIES_WITH.length; k++) { String skip = SKIP_ENTRIES_WITH[k]; if(test.indexOf(skip) > -1) { continue outer; } } list.add(test); } } catch (URISyntaxException e) { e.printStackTrace(); } } Collections.sort(list); renderRequest.setAttribute("jars", list); } private void renderConfirmURL(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { confirmURLView.include(renderRequest, renderResponse); } private void renderTestConnection(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { // Pass on results renderRequest.setAttribute("connectResult", renderRequest.getParameter("connectResult")); renderRequest.setAttribute("connectError", renderRequest.getPortletSession().getAttribute("connectError")); testConnectionView.include(renderRequest, renderResponse); } private void renderPlan(RenderRequest renderRequest, RenderResponse renderResponse, PoolData data) throws IOException, PortletException { // Pass on results renderRequest.setAttribute("deploymentPlan", renderRequest.getPortletSession().getAttribute("deploymentPlan")); // Digest the RAR URI String path = PortletManager.getRepositoryEntry(renderRequest, data.getRarPath()).getPath(); String base = PortletManager.getServerInfo(renderRequest).getCurrentBaseDirectory(); if(base != null && path.startsWith(base)) { path = path.substring(base.length()); if(path.startsWith("/")) { path = path.substring(1); } } else { int pos = path.lastIndexOf('/'); path = path.substring(pos+1); } renderRequest.setAttribute("rarRelativePath", path); planView.include(renderRequest, renderResponse); } private static String attemptConnect(PortletRequest request, PoolData data) throws SQLException, IllegalAccessException, InstantiationException { Class driverClass = attemptDriverLoad(request, data); Driver driver = (Driver) driverClass.newInstance(); if(driver.acceptsURL(data.url)) { Properties props = new Properties(); if(data.user != null) { props.put("user", data.user); } if(data.password != null) { props.put("password", data.password); } Connection con = null; try { con = driver.connect(data.url, props); final DatabaseMetaData metaData = con.getMetaData(); return metaData.getDatabaseProductName()+" "+metaData.getDatabaseProductVersion(); } finally { if(con != null) try{con.close();}catch(SQLException e) {} } } else throw new SQLException("Driver "+data.getDriverClass()+" does not accept URL "+data.url); } private static String save(PortletRequest request, ActionResponse response, PoolData data, boolean planOnly) { ImportStatus status = getImportStatus(request); if(data.objectName == null || data.objectName.equals("")) { // we're creating a new pool data.name = data.name.replaceAll("\\s", ""); DeploymentManager mgr = PortletManager.getDeploymentManager(request); try { URL url = getRAR(request, data.getRarPath()); String str = url.toString(); if(str.indexOf(' ') > -1) { url = new URL(str.replaceAll(" ", "%20")); // try to avoid problems with spaces in path on Windows } ConnectorDeployable deployable = new ConnectorDeployable(url); DeploymentConfiguration config = mgr.createConfiguration(deployable); final DDBeanRoot ddBeanRoot = deployable.getDDBeanRoot(); Connector15DCBRoot root = (Connector15DCBRoot) config.getDConfigBeanRoot(ddBeanRoot); ConnectorDCB connector = (ConnectorDCB) root.getDConfigBean(ddBeanRoot.getChildBean(root.getXpaths()[0])[0]); connector.setConfigID("console-db-pool-"+data.getName()); // Use a parentId of null to pick up the default if(data.jar1 != null && !data.jar1.equals("")) { Dependency dep = new Dependency(); connector.setDependency(new Dependency[]{dep}); dep.setURI(data.jar1); } if(data.jar2 != null && !data.jar2.equals("")) { Dependency dep = new Dependency(); Dependency[] old = connector.getDependency(); Dependency[] longer = new Dependency[old.length+1]; System.arraycopy(old, 0, longer, 0, old.length); longer[old.length] = dep; connector.setDependency(longer); dep.setURI(data.jar2); } if(data.jar3 != null && !data.jar3.equals("")) { Dependency dep = new Dependency(); Dependency[] old = connector.getDependency(); Dependency[] longer = new Dependency[old.length+1]; System.arraycopy(old, 0, longer, 0, old.length); longer[old.length] = dep; connector.setDependency(longer); dep.setURI(data.jar3); } ResourceAdapter adapter = connector.getResourceAdapter()[0]; ConnectionDefinition definition = new ConnectionDefinition(); adapter.setConnectionDefinition(new ConnectionDefinition[]{definition}); definition.setConnectionFactoryInterface("javax.sql.DataSource"); ConnectionDefinitionInstance instance = new ConnectionDefinitionInstance(); definition.setConnectionInstance(new ConnectionDefinitionInstance[]{instance}); instance.setName(data.getName()); ConfigPropertySetting[] settings = instance.getConfigPropertySetting(); if(data.isGeneric()) { // it's a generic TranQL JDBC pool for (int i = 0; i < settings.length; i++) { ConfigPropertySetting setting = settings[i]; if(setting.getName().equals("UserName")) { setting.setValue(data.user); } else if(setting.getName().equals("Password")) { setting.setValue(data.password); } else if(setting.getName().equals("ConnectionURL")) { setting.setValue(data.url); } else if(setting.getName().equals("Driver")) { setting.setValue(data.driverClass); } } } else { // it's an XA driver or non-TranQL RA for (int i = 0; i < settings.length; i++) { ConfigPropertySetting setting = settings[i]; String value = (String) data.properties.get("property-"+setting.getName()); setting.setValue(value == null ? "" : value); } } ConnectionManager manager = instance.getConnectionManager(); manager.setTransactionLocal(true); SinglePool pool = new SinglePool(); manager.setPoolSingle(pool); pool.setMatchOne(true); // Max Size needs to be set before the minimum. This is because // the connection manager will constrain the minimum based on the // current maximum value in the pool. We might consider adding a // setPoolConstraints method to allow specifying both at the same time. if(data.maxSize != null && !data.maxSize.equals("")) { pool.setMaxSize(new Integer(data.maxSize)); } if(data.minSize != null && !data.minSize.equals("")) { pool.setMinSize(new Integer(data.minSize)); } if(data.blockingTimeout != null && !data.blockingTimeout.equals("")) { pool.setBlockingTimeoutMillis(new Integer(data.blockingTimeout)); } if(data.idleTimeout != null && !data.idleTimeout.equals("")) { pool.setIdleTimeoutMinutes(new Integer(data.idleTimeout)); } if(planOnly) { ByteArrayOutputStream out = new ByteArrayOutputStream(); config.save(out); out.close(); return new String(out.toByteArray(), "US-ASCII"); } else { File tempFile = File.createTempFile("console-deployment",".xml"); tempFile.deleteOnExit(); log.debug("Writing database pool deployment plan to "+tempFile.getAbsolutePath()); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile)); config.save(out); out.flush(); out.close(); Target[] targets = mgr.getTargets(); ProgressObject po = mgr.distribute(targets, new File(url.getPath()), tempFile); waitForProgress(po); if(po.getDeploymentStatus().isCompleted()) { TargetModuleID[] ids = po.getResultTargetModuleIDs(); po = mgr.start(ids); waitForProgress(po); if(po.getDeploymentStatus().isCompleted()) { ids = po.getResultTargetModuleIDs(); if(status != null) { status.getCurrentPool().setName(data.getName()); status.getCurrentPool().setConfigurationName(ids[0].getModuleID()); status.getCurrentPool().setFinished(true); response.setRenderParameter(MODE_KEY, IMPORT_STATUS_MODE); } System.out.println("Deployment completed successfully!"); } } } } catch (Exception e) { log.error("Unable to save connection pool", e); } finally { if(mgr != null) mgr.release(); } } else { // We're saving updates to an existing pool if(planOnly) { throw new UnsupportedOperationException("Can't update a plan for an existing deployment"); } try { JCAManagedConnectionFactory factory = (JCAManagedConnectionFactory) PortletManager.getManagedBean(request, data.getObjectName()); if(data.isGeneric()) { factory.setConfigProperty("connectionURL", data.getUrl()); factory.setConfigProperty("userName", data.getUser()); factory.setConfigProperty("password", data.getPassword()); } else { for (Iterator it = data.getProperties().entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); factory.setConfigProperty(((String) entry.getKey()).substring("property-".length()), entry.getValue()); } } //todo: push the lookup into ManagementHelper PoolingAttributes pool = (PoolingAttributes) PortletManager.getManagedBean(request, factory.getConnectionManager()); pool.setPartitionMinSize(data.minSize == null || data.minSize.equals("") ? 0 : Integer.parseInt(data.minSize)); pool.setPartitionMaxSize(data.maxSize == null || data.maxSize.equals("") ? 10 : Integer.parseInt(data.maxSize)); pool.setBlockingTimeoutMilliseconds(data.blockingTimeout == null || data.blockingTimeout.equals("") ? 5000 : Integer.parseInt(data.blockingTimeout)); pool.setIdleTimeoutMinutes(data.idleTimeout == null || data.idleTimeout.equals("") ? 15 : Integer.parseInt(data.idleTimeout)); } catch (Exception e) { log.error("Unable to save connection pool", e); } } return null; } private static void waitForProgress(ProgressObject po) { while(po.getDeploymentStatus().isRunning()) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } private static ImportStatus getImportStatus(PortletRequest request) { return (ImportStatus) request.getPortletSession(true).getAttribute("ImportStatus"); } private static URL getRAR(PortletRequest request, String rarPath) { try { URI uri = new URI(rarPath); Repository[] repos = PortletManager.getRepositories(request); for (int i = 0; i < repos.length; i++) { Repository repo = repos[i]; URL url = repo.getURL(uri); if(url != null && url.getProtocol().equals("file")) { File file = new File(url.getPath()); if(file.exists() && file.canRead() && !file.isDirectory()) { return url; } } } } catch (URISyntaxException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } return null; } /** * WARNING: This method relies on having access to the same repository * URLs as the server uses. */ private static Class attemptDriverLoad(PortletRequest request, PoolData data) { List list = new ArrayList(); try { URI one = data.getJar1() == null ? null : new URI(data.getJar1()); URI two = data.getJar2() == null ? null : new URI(data.getJar2()); URI three = data.getJar3() == null ? null : new URI(data.getJar3()); ListableRepository[] repos = PortletManager.getListableRepositories(request); for (int i = 0; i < repos.length; i++) { ListableRepository repo = repos[i]; if(one != null) { URL url = repo.getURL(one); if(url != null) { list.add(url); one = null; } } if(two != null) { URL url = repo.getURL(two); if(url != null) { list.add(url); two = null; } } if(three != null) { URL url = repo.getURL(three); if(url != null) { list.add(url); three = null; } } } URLClassLoader loader = new URLClassLoader((URL[]) list.toArray(new URL[list.size()]), DatabasePoolPortlet.class.getClassLoader()); try { return loader.loadClass(data.driverClass); } catch (ClassNotFoundException e) { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } private static String populateURL(String url, String[] keys, Map properties) { for (int i = 0; i < keys.length; i++) { String key = keys[i]; String value = (String) properties.get("urlproperty-"+key); if(value == null || value.equals("")) { int begin = url.indexOf("<"+key+">"); int end = begin + key.length() + 2; for(int j=begin-1; j>=0; j--) { char c = url.charAt(j); if(c == ';' || c == ':') { begin = j; break; } else if(c == '/') { if(url.length() > end && url.charAt(end) == '/') { begin = j; // Don't leave // if foo is null for /<foo>/ } break; } } url = url.substring(0, begin)+url.substring(end); } else { url = url.replaceAll("<"+key+">", value); } } return url; } private static DatabaseInfo getDatabaseInfo(PoolData data) { DatabaseInfo info = null; for (int i = 0; i < DatabaseInfo.ALL_DATABASES.length; i++) { DatabaseInfo next = DatabaseInfo.ALL_DATABASES[i]; if(next.getName().equals(data.getDbtype())) { info = next; break; } } return info; } private static DatabaseInfo getDatabaseInfoFromDriver(PoolData data) { DatabaseInfo info = null; for (int i = 0; i < DatabaseInfo.ALL_DATABASES.length; i++) { DatabaseInfo next = DatabaseInfo.ALL_DATABASES[i]; if(next.getDriverClass() != null && next.getDriverClass().equals(data.getDriverClass())) { info = next; break; } } return info; } public static class PoolData implements Serializable { private String name; private String dbtype; private String user; private String password; private Map properties = new HashMap(); // Configuration for non-Generic drivers private Map urlProperties = new HashMap(); // URL substitution for Generic drivers private Map propertyNames; //todo: store these in the ConfigParam instead private String driverClass; private String url; private String urlPrototype; private String jar1; private String jar2; private String jar3; private String minSize; private String maxSize; private String blockingTimeout; private String idleTimeout; private String objectName; private String adapterDisplayName; private String adapterDescription; private String rarPath; private String importSource; private Map objectNameMap; // generated as needed, don't need to read/write it public void load(PortletRequest request) { name = request.getParameter("name"); if(name != null && name.equals("")) name = null; driverClass = request.getParameter("driverClass"); if(driverClass != null && driverClass.equals("")) driverClass = null; dbtype = request.getParameter("dbtype"); if(dbtype != null && dbtype.equals("")) dbtype = null; user = request.getParameter("user"); if(user != null && user.equals("")) user = null; password = request.getParameter("password"); if(password != null && password.equals("")) password = null; url = request.getParameter("url"); if(url != null && url.equals("")) { url = null; } else if(url != null && url.indexOf("%3B") > -1) { url = url.replaceAll("%3B", ";"); // attempt to work around Pluto/Tomcat error with ; in a stored value } urlPrototype = request.getParameter("urlPrototype"); if(urlPrototype != null && urlPrototype.equals("")) urlPrototype = null; jar1 = request.getParameter("jar1"); if(jar1 != null && jar1.equals("")) jar1 = null; jar2 = request.getParameter("jar2"); if(jar2 != null && jar2.equals("")) jar2 = null; jar3 = request.getParameter("jar3"); if(jar3 != null && jar3.equals("")) jar3 = null; minSize = request.getParameter("minSize"); if(minSize != null && minSize.equals("")) minSize = null; maxSize = request.getParameter("maxSize"); if(maxSize != null && maxSize.equals("")) maxSize = null; blockingTimeout = request.getParameter("blockingTimeout"); if(blockingTimeout != null && blockingTimeout.equals("")) blockingTimeout = null; idleTimeout = request.getParameter("idleTimeout"); if(idleTimeout != null && idleTimeout.equals("")) idleTimeout = null; objectName = request.getParameter("objectName"); if(objectName != null && objectName.equals("")) objectName = null; adapterDisplayName = request.getParameter("adapterDisplayName"); if(adapterDisplayName != null && adapterDisplayName.equals("")) adapterDisplayName = null; adapterDescription = request.getParameter("adapterDescription"); if(adapterDescription != null && adapterDescription.equals("")) adapterDescription = null; rarPath = request.getParameter("rarPath"); if(rarPath != null && rarPath.equals("")) rarPath = null; importSource = request.getParameter("importSource"); if(importSource != null && importSource.equals("")) importSource = null; Map map = request.getParameterMap(); propertyNames = new HashMap(); for (Iterator it = map.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); if(key.startsWith("urlproperty-")) { urlProperties.put(key, request.getParameter(key)); } else if(key.startsWith("property-")) { properties.put(key, request.getParameter(key)); propertyNames.put(key, getPropertyName(key)); } } } public void loadPropertyNames() { propertyNames = new HashMap(); for (Iterator it = properties.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); propertyNames.put(key, getPropertyName(key)); } } private static String getPropertyName(String key) { int pos = key.indexOf('-'); key = Character.toUpperCase(key.charAt(pos+1))+key.substring(pos+2); StringBuffer buf = new StringBuffer(); pos = 0; for(int i=1; i<key.length(); i++) { if(Character.isUpperCase(key.charAt(i))) { if(Character.isUpperCase(key.charAt(i-1))) { // ongoing capitalized word } else { // start of a new word buf.append(key.substring(pos, i)).append(" "); pos = i; } } else { if(Character.isUpperCase(key.charAt(i-1)) && i-pos > 1) { // first lower-case after a series of caps buf.append(key.substring(pos, i-1)).append(" "); pos = i-1; } } } buf.append(key.substring(pos)); return buf.toString(); } public void store(ActionResponse response) { if(name != null) response.setRenderParameter("name", name); if(dbtype != null) response.setRenderParameter("dbtype", dbtype); if(driverClass != null) response.setRenderParameter("driverClass", driverClass); if(user != null) response.setRenderParameter("user", user); if(password != null) response.setRenderParameter("password", password); if(url != null) { // attempt to work around Pluto/Tomcat error with ; in a stored value response.setRenderParameter("url", url.replaceAll(";", "%3B")); } if(urlPrototype != null) response.setRenderParameter("urlPrototype", urlPrototype); if(jar1 != null) response.setRenderParameter("jar1", jar1); if(jar2 != null) response.setRenderParameter("jar2", jar2); if(jar3 != null) response.setRenderParameter("jar3", jar3); if(minSize != null) response.setRenderParameter("minSize", minSize); if(maxSize != null) response.setRenderParameter("maxSize", maxSize); if(blockingTimeout != null) response.setRenderParameter("blockingTimeout", blockingTimeout); if(idleTimeout != null) response.setRenderParameter("idleTimeout", idleTimeout); if(objectName != null) response.setRenderParameter("objectName", objectName); if(adapterDisplayName != null) response.setRenderParameter("adapterDisplayName", adapterDisplayName); if(adapterDescription != null) response.setRenderParameter("adapterDescription", adapterDescription); if(importSource != null) response.setRenderParameter("importSource", importSource); if(rarPath != null) response.setRenderParameter("rarPath", rarPath); for (Iterator it = urlProperties.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); if(entry.getValue() != null) { response.setRenderParameter((String)entry.getKey(), (String)entry.getValue()); } } for (Iterator it = properties.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); if(entry.getValue() != null) { response.setRenderParameter((String)entry.getKey(), (String)entry.getValue()); } } } public String getName() { return name; } public String getDbtype() { return dbtype; } public String getUser() { return user; } public String getPassword() { return password; } public Map getProperties() { return properties; } public Map getPropertyNames() { return propertyNames; } public Map getUrlProperties() { return urlProperties; } public String getUrl() { return url; } public String getJar1() { return jar1; } public String getJar2() { return jar2; } public String getJar3() { return jar3; } public String getMinSize() { return minSize; } public String getMaxSize() { return maxSize; } public String getBlockingTimeout() { return blockingTimeout; } public String getIdleTimeout() { return idleTimeout; } public String getDriverClass() { return driverClass; } public String getUrlPrototype() { return urlPrototype; } public String getObjectName() { return objectName; } public String getAdapterDisplayName() { return adapterDisplayName; } public String getAdapterDescription() { return adapterDescription; } public String getRarPath() { return rarPath; } public boolean isGeneric() { //todo: is there any better way to tell? return adapterDisplayName == null || adapterDisplayName.equals("TranQL Generic JDBC Resource Adapter"); } public String getImportSource() { return importSource; } public Map getObjectNameMap() { if(objectName == null) return Collections.EMPTY_MAP; if(objectNameMap != null) return objectNameMap; try { ObjectName name = new ObjectName(objectName); objectNameMap = new HashMap(name.getKeyPropertyList()); objectNameMap.put("domain", name.getDomain()); return objectNameMap; } catch (MalformedObjectNameException e) { return Collections.EMPTY_MAP; } } } public static class ConnectionPool implements Serializable, Comparable { private final String adapterObjectName; private final String factoryObjectName; private final String name; private final String parentName; private final int state; public ConnectionPool(ObjectName adapterObjectName, String factoryObjectName, String name, int state) { this.adapterObjectName = adapterObjectName.getCanonicalName(); String parent = adapterObjectName.getKeyProperty(NameFactory.J2EE_APPLICATION); if(parent != null && parent.equals("null")) { parent = null; } parentName = parent; this.factoryObjectName = factoryObjectName; this.name = name; this.state = state; } public String getAdapterObjectName() { return adapterObjectName; } public String getFactoryObjectName() { return factoryObjectName; } public String getName() { return name; } public String getParentName() { return parentName; } public int getState() { return state; } public String getStateName() { return State.toString(state); } public int compareTo(Object o) { final ConnectionPool pool = (ConnectionPool)o; int names = name.compareTo(pool.name); if(parentName == null) { if(pool.parentName == null) { return names; } else { return -1; } } else { if(pool.parentName == null) { return 1; } else { int test = parentName.compareTo(pool.parentName); if(test != 0) { return test; } else { return names; } } } } } public static class ResourceAdapterParams { private String displayName; private String description; private ConfigParam[] configParams; public ResourceAdapterParams(String displayName, String description, ConfigParam[] configParams) { this.displayName = displayName; this.description = description; this.configParams = configParams; } public String getDisplayName() { return displayName; } public String getDescription() { return description; } public ConfigParam[] getConfigParams() { return configParams; } } public static class ConfigParam { private String name; private String type; private String description; private String defaultValue; public ConfigParam(String name, String type, String description, String defaultValue) { this.name = name; this.type = type; this.description = description; this.defaultValue = defaultValue; } public String getName() { return name; } public String getType() { return type; } public String getDescription() { return description; } public String getDefaultValue() { return defaultValue; } } }