Java tutorial
/* * Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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.wso2.carbon.registry.core.utils; import javax.cache.Cache; import javax.cache.CacheManager; import javax.cache.Caching; import org.apache.axiom.om.OMElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.registry.api.GhostResource; import org.wso2.carbon.registry.core.*; import org.wso2.carbon.registry.core.Collection; import org.wso2.carbon.registry.core.CollectionImpl; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.RegistryConstants; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.ResourceIDImpl; import org.wso2.carbon.registry.core.ResourceImpl; import org.wso2.carbon.registry.core.ResourcePath; import org.wso2.carbon.registry.core.caching.RegistryCacheEntry; import org.wso2.carbon.registry.core.caching.RegistryCacheKey; import org.wso2.carbon.registry.core.config.Mount; import org.wso2.carbon.registry.core.config.RegistryContext; import org.wso2.carbon.registry.core.config.RemoteConfiguration; import org.wso2.carbon.registry.core.config.StaticConfiguration; import org.wso2.carbon.registry.core.dao.ResourceDAO; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.internal.RegistryCoreServiceComponent; import org.wso2.carbon.registry.core.jdbc.handlers.HandlerLifecycleManager; import org.wso2.carbon.registry.core.jdbc.handlers.HandlerManager; import org.wso2.carbon.registry.core.jdbc.handlers.RequestContext; import org.wso2.carbon.registry.core.jdbc.handlers.builtin.MountHandler; import org.wso2.carbon.registry.core.jdbc.handlers.builtin.SymLinkHandler; import org.wso2.carbon.registry.core.jdbc.handlers.filters.Filter; import org.wso2.carbon.registry.core.jdbc.handlers.filters.URLMatcher; import org.wso2.carbon.registry.core.jdbc.realm.RegistryRealm; import org.wso2.carbon.registry.core.jdbc.utils.ServiceConfigUtil; import org.wso2.carbon.registry.core.jdbc.utils.Transaction; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.session.CurrentSession; import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.registry.core.statistics.StatisticsCollector; import org.wso2.carbon.user.api.RealmConfiguration; import org.wso2.carbon.user.core.UserRealm; import org.wso2.carbon.user.core.UserStoreException; import org.wso2.carbon.user.core.UserStoreManager; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.ServerConstants; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import javax.servlet.http.HttpServletResponse; import javax.xml.namespace.QName; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.*; import java.util.regex.Pattern; /** * This class contains a set of useful utility methods used by the Registry Kernel. These can also * be used by third party components as well as the various clients written to access the registry * via its remote APIs. */ public final class RegistryUtils { private static final Log log = LogFactory.getLog(RegistryUtils.class); private static final String ENCODING = System.getProperty("carbon.registry.character.encoding"); private static final String MY_SQL_PRODUCT_NAME = "MySQL"; private RegistryUtils() { } /** * Paths referring to a version of a resource are in the form /c1/c2/r1?v=2. Give a such version * path, this method extracts the valid pure path and the version number of the resource. Note * that this method should only be used for pure resource paths. * * @param resourcePath versioned resource path. * * @return VersionPath object containing the valid resource path and the version number. */ public static VersionedPath getVersionedPath(ResourcePath resourcePath) { String versionString = resourcePath.getParameterValue("version"); long versionNumber = -1; if (versionString != null) { versionNumber = Long.parseLong(versionString); } String plainPath = getPureResourcePath(resourcePath.getPath()); VersionedPath versionedPath = new VersionedPath(); versionedPath.setPath(plainPath); versionedPath.setVersion(versionNumber); return versionedPath; } /** * Convert an input stream into a byte array. * * @param inputStream the input stream. * * @return the byte array. * @throws RegistryException if the operation failed. */ public static byte[] getByteArray(InputStream inputStream) throws RegistryException { if (inputStream == null) { String msg = "Could not create memory based content for null input stream."; log.error(msg); throw new RegistryException(msg); } ByteArrayOutputStream out = null; try { out = new ByteArrayOutputStream(); byte[] contentChunk = new byte[RegistryConstants.DEFAULT_BUFFER_SIZE]; int byteCount; while ((byteCount = inputStream.read(contentChunk)) != -1) { out.write(contentChunk, 0, byteCount); } out.flush(); return out.toByteArray(); } catch (IOException e) { String msg = "Failed to write data to byte array input stream. " + e.getMessage(); log.error(msg, e); throw new RegistryException(msg, e); } finally { try { inputStream.close(); if (out != null) { out.close(); } } catch (IOException e) { String msg = "Failed to close streams used for creating memory stream. " + e.getMessage(); log.error(msg, e); } } } /** * Create an in-memory input stream for the given input stream. * * @param inputStream the input stream. * * @return the in-memory input stream. * @throws RegistryException if the operation failed. */ public static InputStream getMemoryStream(InputStream inputStream) throws RegistryException { return new ByteArrayInputStream(getByteArray(inputStream)); } /** * Method to obtain a unique identifier for the database connection. * * @param connection the database connection. * * @return the unique identifier. */ public static String getConnectionId(Connection connection) { String connectionId = null; try { // The connection URL is unique enough to be used as an identifier since one thread // makes one connection to the given URL according to our model. DatabaseMetaData connectionMetaData = connection.getMetaData(); if (connectionMetaData != null) { String productName = connectionMetaData.getDatabaseProductName(); if (MY_SQL_PRODUCT_NAME.equals(productName)) { /* For MySQL getUserName() method executes 'SELECT USER()' query on DB via mysql connector causing a huge number of 'SELECT USER()' queries to be executed. Hence removing username when the DB in use is MySQL. */ connectionId = connectionMetaData.getURL(); } else { connectionId = (connectionMetaData.getUserName() != null ? connectionMetaData.getUserName().split("@")[0] : connectionMetaData.getUserName()) + "@" + connectionMetaData.getURL(); } } } catch (SQLException e) { log.error("Failed to construct the connectionId.", e); } return connectionId; } /** * Builds the cache key for a resource path. * * @param connectionId the database connection identifier * @param tenantId the tenant identifier * @param resourcePath the resource path * * @return the cache key. */ public static RegistryCacheKey buildRegistryCacheKey(String connectionId, int tenantId, String resourcePath) { RegistryContext registryContext = RegistryContext.getBaseInstance(); String absoluteLocalRepositoryPath = getAbsolutePath(registryContext, RegistryConstants.LOCAL_REPOSITORY_BASE_PATH); if (resourcePath != null && resourcePath.startsWith(absoluteLocalRepositoryPath)) { return new RegistryCacheKey(resourcePath, tenantId, registryContext.getNodeIdentifier() + ":" + connectionId.toLowerCase()); } else { return new RegistryCacheKey(resourcePath, tenantId, connectionId.toLowerCase()); } } /** * All "valid" paths pure resources should be in the form /c1/c2/r1. That is they should start * with "/" and should not end with "/". Given a path of a pure resource, this method prepares * the valid path for that path. * * @param resourcePath Path of a pure resource. * * @return Valid path of the pure resource. */ public static String getPureResourcePath(String resourcePath) { if (resourcePath == null) { return null; } String preparedPath = resourcePath; if (preparedPath.equals(RegistryConstants.ROOT_PATH)) { return preparedPath; } else { if (!preparedPath.startsWith(RegistryConstants.ROOT_PATH)) { preparedPath = RegistryConstants.ROOT_PATH + preparedPath; } if (preparedPath.endsWith(RegistryConstants.PATH_SEPARATOR)) { preparedPath = preparedPath.substring(0, preparedPath.length() - 1); } if (preparedPath.contains("//")) { preparedPath = preparedPath.replace("//", "/"); } } return preparedPath; } /** * Return an instance of a named cache that is common to all tenants. * * @param name the name of the cache. * * @return the named cache instance. */ // public static Cache getCommonCache(String name) { // // We create a single cache for all tenants. It is not a good choice to create per-tenant // // caches in this case. We qualify tenants by adding the tenant identifier in the cache key. // PrivilegedCarbonContext currentContext = PrivilegedCarbonContext.getCurrentContext(); // currentContext.startTenantFlow(); // try { // currentContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); // return CarbonUtils.getLocalCache(name); // } finally { // currentContext.endTenantFlow(); // } // } /** * Method used to retrieve cache object for resources * @param name the name of the cache * @return the cache object for the given cache manger and cache name */ public static Cache<RegistryCacheKey, GhostResource> getResourceCache(String name) { CacheManager manager = getCacheManager(); return (manager != null) ? manager.<RegistryCacheKey, GhostResource>getCache(name) : Caching.getCacheManager().<RegistryCacheKey, GhostResource>getCache(name); } /** * Method used to retrieve cache object for resource paths. * @param name the name of the cache * @return the cache object for the given cache manger and cache name */ public static Cache<RegistryCacheKey, RegistryCacheEntry> getResourcePathCache(String name) { CacheManager manager = getCacheManager(); return (manager != null) ? manager.<RegistryCacheKey, RegistryCacheEntry>getCache(name) : Caching.getCacheManager().<RegistryCacheKey, RegistryCacheEntry>getCache(name); } /** * Method used to retrieve cache object for UUID, resource paths. * @param name the name of the cache * @return the cache object for the given cache manger and cache name */ public static Cache<String, String> getUUIDCache(String name) { CacheManager manager = getCacheManager(); return (manager != null) ? manager.<String, String>getCache(name) : Caching.getCacheManager().<String, String>getCache(name); } private static CacheManager getCacheManager() { return Caching.getCacheManagerFactory().getCacheManager(RegistryConstants.REGISTRY_CACHE_MANAGER); } /** * Method to obtain the parent path of the given resource path. * * @param resourcePath the resource path. * * @return the parent path. */ public static String getParentPath(String resourcePath) { if (resourcePath == null) { return null; } String parentPath; if (resourcePath.equals(RegistryConstants.ROOT_PATH)) { parentPath = null; } else { String formattedPath = resourcePath; if (resourcePath.endsWith(RegistryConstants.PATH_SEPARATOR)) { formattedPath = resourcePath.substring(0, resourcePath.length() - RegistryConstants.PATH_SEPARATOR.length()); } if (formattedPath.lastIndexOf(RegistryConstants.PATH_SEPARATOR) <= 0) { parentPath = RegistryConstants.ROOT_PATH; } else { parentPath = formattedPath.substring(0, formattedPath.lastIndexOf(RegistryConstants.PATH_SEPARATOR)); } } return parentPath; } /** * Returns resource name when full resource path is passed. * * @param resourcePath full resource path. * * @return the resource name. */ public static String getResourceName(String resourcePath) { String resourceName; if (resourcePath.equals(RegistryConstants.ROOT_PATH)) { resourceName = RegistryConstants.ROOT_PATH; } else { String formattedPath = resourcePath; if (resourcePath.endsWith(RegistryConstants.PATH_SEPARATOR)) { formattedPath = resourcePath.substring(0, resourcePath.length() - RegistryConstants.PATH_SEPARATOR.length()); } if (formattedPath.lastIndexOf(RegistryConstants.PATH_SEPARATOR) == 0) { resourceName = formattedPath.substring(1, formattedPath.length()); } else { resourceName = formattedPath.substring( formattedPath.lastIndexOf(RegistryConstants.PATH_SEPARATOR) + 1, formattedPath.length()); } } return resourceName; } /** * Method to redirect a given response to some URL. * * @param response the HTTP Response. * @param url The URL to redirect to. */ public static void redirect(HttpServletResponse response, String url) { try { response.sendRedirect(url); } catch (IOException e) { String msg = "Failed to redirect to the URL " + url + ". \nCaused by " + e.getMessage(); log.error(msg, e); } } /** * Prepare the given path as a general resource path to be used in the registry. General * resource paths may refer to pure resources or virtual resources. * * @param rawPath Raw path to be prepared * * @return Prepared general resource path */ public static String prepareGeneralPath(String rawPath) { String path = rawPath; // path should always start with "/" if (!rawPath.startsWith(RegistryConstants.ROOT_PATH)) { path = RegistryConstants.ROOT_PATH + rawPath; } return path; } /** * Method to determine whether the given user is in an admin role. * * @param userName the user name. * @param userRealm the user realm. * * @return true if the user is in the admin role, or false otherwise. * @throws RegistryException if the operation failed. */ public static boolean hasAdminAuthorizations(String userName, UserRealm userRealm) throws RegistryException { try { UserStoreManager userStoreReader = userRealm.getUserStoreManager(); RealmConfiguration realmConfig; try { realmConfig = userRealm.getRealmConfiguration(); } catch (UserStoreException e) { String msg = "Failed to retrieve realm configuration."; log.error(msg, e); throw new RegistryException(msg, e); } String systemUser = CarbonConstants.REGISTRY_SYSTEM_USERNAME; if (systemUser.equals(userName)) { return true; } String adminUser = realmConfig.getAdminUserName(); if (adminUser.equals(userName)) { return true; } String[] roles = userStoreReader.getRoleListOfUser(userName); String adminRoleName = realmConfig.getAdminRoleName(); if (containsString(adminRoleName, roles)) { return true; } } catch (UserStoreException e) { String msg = "Failed to check authorization level of user " + userName + ". Caused by: " + e.getMessage(); log.error(msg, e); throw new RegistryException(msg, e); } return false; } /** * Method to determine whether the given array of strings contains the given string. * * @param value the string to search. * @param array the array of string. * * @return whether the given string was found. */ public static boolean containsString(String value, String[] array) { boolean found = false; for (String anArray : array) { if (anArray.equals(value)) { found = true; } } return found; } /** * Method to determine whether the given array of strings contains a string which has the given * string as a portion (sub-string) of it. * * @param value the string to search. * @param array the array of string. * * @return whether the given string was found. */ public static boolean containsAsSubString(String value, String[] array) { for (String anArray : array) { if (anArray.contains(value)) { return true; } } return false; } /** * Method to remove the author and updater from a dump. * * @param root the input XML element. * * @return the output which contains the input XML element, but without details of the author * and the updater. */ @SuppressWarnings("unused") public static OMElement removeAuthorUpdaterFromDump(OMElement root) { Iterator children = root.getChildren(); String isCollectionString = root.getAttributeValue(new QName("isCollection")); boolean isCollection = isCollectionString.equals("true"); OMElement creatorEle = null; OMElement createdTimeEle = null; OMElement lastUpdaterEle = null; OMElement lastModifiedTimeEle = null; OMElement childrenEle = null; while (children.hasNext()) { Object nextChild = children.next(); if (!(nextChild instanceof OMElement)) { continue; } OMElement child = (OMElement) nextChild; String localName = child.getLocalName(); // creator if (localName.equals("creator")) { creatorEle = child; } // createdTime else if (localName.equals("createdTime")) { createdTimeEle = child; } // setLastUpdater else if (localName.equals("lastUpdater")) { lastUpdaterEle = child; } // LastModified else if (localName.equals("lastModified")) { lastModifiedTimeEle = child; } else if (localName.equals("children")) { childrenEle = child; } } // removing the children if (creatorEle != null) { creatorEle.detach(); } if (createdTimeEle != null) { createdTimeEle.detach(); } if (lastUpdaterEle != null) { lastUpdaterEle.detach(); } if (lastModifiedTimeEle != null) { lastModifiedTimeEle.detach(); } // call this for all the children if (isCollection && childrenEle != null) { Iterator grandChildren = childrenEle.getChildren(); while (grandChildren.hasNext()) { Object nextChild = grandChildren.next(); if (!(nextChild instanceof OMElement)) { continue; } OMElement childE = (OMElement) nextChild; removeAuthorUpdaterFromDump(childE); } } return root; } @Deprecated @SuppressWarnings("unused") public static void addRootCollectionAuthorization(UserRealm userRealm) throws RegistryException { AuthorizationUtils.setRootAuthorizations(RegistryConstants.ROOT_PATH, userRealm); } /** * Set-up the system properties required to access the trust-store in Carbon. This is used in * the atom-based Remote Registry implementation. */ public static void setTrustStoreSystemProperties() { ServerConfiguration config = ServerConfiguration.getInstance(); String type = config.getFirstProperty("Security.TrustStore.Type"); String password = config.getFirstProperty("Security.TrustStore.Password"); String storeFile = new File(config.getFirstProperty("Security.TrustStore.Location")).getAbsolutePath(); System.setProperty("javax.net.ssl.trustStore", storeFile); System.setProperty("javax.net.ssl.trustStoreType", type); System.setProperty("javax.net.ssl.trustStorePassword", password); } /** * Method to determine whether a system resource (or collection) is existing or whether it * should be created. Once it has been identified that a system collection is existing, it will * not be checked against a database until the server has been restarted. * * @param registry the base registry to use. * @param absolutePath the absolute path of the system resource (or collection) * * @return whether the system resource (or collection) needs to be added. * * @throws RegistryException if an error occurred. */ public static boolean systemResourceShouldBeAdded(Registry registry, String absolutePath) throws RegistryException { RegistryContext registryContext = registry.getRegistryContext(); if (registryContext == null) { registryContext = RegistryContext.getBaseInstance(); } if (registryContext.isSystemResourcePathRegistered(absolutePath)) { return false; } else if (registry.resourceExists(absolutePath)) { registryContext.registerSystemResourcePath(absolutePath); return false; } return true; } /** * Method to determine whether a system resource (or collection) is existing or whether it * should be created. Once it has been identified that a system collection is existing, it will * not be checked against a database until the server has been restarted. * * @param dataAccessObject the resource data access object. * @param absolutePath the absolute path of the system resource (or collection) * * @return whether the system resource (or collection) needs to be added. * * @throws RegistryException if an error occurred. */ public static boolean systemResourceShouldBeAdded(ResourceDAO dataAccessObject, String absolutePath) throws RegistryException { RegistryContext registryContext = RegistryContext.getBaseInstance(); if (RegistryContext.getBaseInstance().isSystemResourcePathRegistered(absolutePath)) { return false; } else if (dataAccessObject.resourceExists(absolutePath)) { registryContext.registerSystemResourcePath(absolutePath); return false; } return true; } /** * This method builds the base collection structure for the registry. The base <b>_system</b> * collection, and the remaining local, config and governance collections will be created as a * result. * * @param registry the base registry to use. * @param userRealm the user realm. * * @throws RegistryException if an error occurred. */ @SuppressWarnings("unused") public static void addBaseCollectionStructure(Registry registry, UserRealm userRealm) throws RegistryException { RegistryContext registryContext = registry.getRegistryContext(); // Registry Context stays the same during the scope of this operation. if (log.isTraceEnabled()) { log.trace("Checking the existence of '" + RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.SYSTEM_COLLECTION_BASE_PATH) + "' collection of the Registry."); } if (systemResourceShouldBeAdded(registry, RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.SYSTEM_COLLECTION_BASE_PATH))) { if (registryContext != null && registryContext.isClone()) { return; } if (log.isTraceEnabled()) { log.trace( "Creating the '" + RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.SYSTEM_COLLECTION_BASE_PATH) + "' collection of the Registry."); } CollectionImpl systemCollection = (CollectionImpl) registry.newCollection(); String systemDescription = "System collection of the Registry. This collection is " + "used to store the resources required by the carbon server."; systemCollection.setDescription(systemDescription); registry.put( RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.SYSTEM_COLLECTION_BASE_PATH), systemCollection); systemCollection.discard(); CollectionImpl localRepositoryCollection = (CollectionImpl) registry.newCollection(); String localRepositoryDescription = "Local data repository of the carbon server. This " + "collection is used to store the resources local to this carbon " + "server instance."; localRepositoryCollection.setDescription(localRepositoryDescription); registry.put( RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.LOCAL_REPOSITORY_BASE_PATH), localRepositoryCollection); localRepositoryCollection.discard(); CollectionImpl configRegistryCollection = (CollectionImpl) registry.newCollection(); String configRegistryDescription = "Configuration registry of the carbon server. " + "This collection is used to store the resources of this product cluster."; configRegistryCollection.setDescription(configRegistryDescription); registry.put( RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.CONFIG_REGISTRY_BASE_PATH), configRegistryCollection); configRegistryCollection.discard(); CollectionImpl governanceRegistryCollection = (CollectionImpl) registry.newCollection(); String governanceRegistryDescription = "Governance registry of the carbon server. " + "This collection is used to store the resources common to the whole " + "platform."; governanceRegistryCollection.setDescription(governanceRegistryDescription); registry.put( RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH), governanceRegistryCollection); governanceRegistryCollection.discard(); } // This is to create the repository collections for the various registries and clean // them at start-up, if needed. boolean cleanRegistry = false; if (System.getProperty(RegistryConstants.CARBON_REGISTRY_CLEAN) != null) { cleanRegistry = true; System.clearProperty(RegistryConstants.CARBON_REGISTRY_CLEAN); } if (cleanRegistry) { cleanArtifactLCs(registry); } for (String repositoryPath : new String[] { RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + "/repository"), RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH + "/repository"), RegistryUtils.getAbsolutePath(registryContext, RegistryConstants.CONFIG_REGISTRY_BASE_PATH + "/repository") }) { if (cleanRegistry) { if (registry.resourceExists(repositoryPath)) { try { registry.delete(repositoryPath); log.info("Cleaned the registry space of carbon at path: " + repositoryPath); } catch (Exception e) { log.error("An error occurred while cleaning of registry space of carbon " + "at path: " + repositoryPath, e); } } } else if (systemResourceShouldBeAdded(registry, repositoryPath)) { registry.put(repositoryPath, registry.newCollection()); } } } /** * This method is used to remove LC information from artifacts when clean up operation is done. * @param registry * @throws RegistryException */ private static void cleanArtifactLCs(Registry registry) throws RegistryException { String resourcePaths[]; String collectionpaths[]; String resourceQuery = "SELECT R.REG_PATH_ID, R.REG_NAME FROM REG_RESOURCE R, REG_PROPERTY PP, " + "REG_RESOURCE_PROPERTY RP WHERE"; String collectionQuery = "SELECT R.REG_PATH_ID, R.REG_NAME FROM REG_RESOURCE R, REG_PROPERTY PP, " + "REG_RESOURCE_PROPERTY RP WHERE"; if (StaticConfiguration.isVersioningProperties()) { resourceQuery += "R.REG_VERSION=RP.REG_VERSION AND " + "RP.REG_PROPERTY_ID=PP.REG_ID AND lower(PP.REG_NAME) LIKE ?"; } else { resourceQuery += "R.REG_PATH_ID=RP.REG_PATH_ID AND " + "((R.REG_NAME = RP.REG_RESOURCE_NAME)) AND " + "RP.REG_PROPERTY_ID=PP.REG_ID AND lower(PP.REG_NAME) LIKE ?"; } if (StaticConfiguration.isVersioningProperties()) { collectionQuery += "R.REG_VERSION=RP.REG_VERSION AND " + "RP.REG_PROPERTY_ID=PP.REG_ID AND lower(PP.REG_NAME) LIKE ? AND R.REG_NAME IS NULL"; } else { collectionQuery += "R.REG_PATH_ID=RP.REG_PATH_ID AND " + "R.REG_NAME IS NULL AND RP.REG_RESOURCE_NAME IS NULL AND " + "RP.REG_PROPERTY_ID=PP.REG_ID AND lower(PP.REG_NAME) LIKE ? AND R.REG_NAME IS NULL"; } Map<String, Object> paramMapResources = new HashMap<String, Object>(); paramMapResources.put("1", "registry.lc.name"); paramMapResources.put("query", resourceQuery); Map<String, Object> paramMapCollections = new HashMap<String, Object>(); paramMapCollections.put("1", "registry.lc.name"); paramMapCollections.put("query", collectionQuery); resourcePaths = (String[]) registry.executeQuery(null, paramMapResources).getContent(); collectionpaths = (String[]) registry.executeQuery(null, paramMapCollections).getContent(); for (String path : resourcePaths) { removeArtifactLC(path, registry); } for (String path : collectionpaths) { removeArtifactLC(path, registry); } } /** * Method to remove Lifecycle from a given resource on the registry. * * @param path the path of the resource. * @param registry the registry instance on which the resource is available. * * @throws RegistryException if the operation failed. */ private static void removeArtifactLC(String path, Registry registry) throws RegistryException { try { /* set all the variables to the resource */ Resource resource = registry.get(path); Properties props = resource.getProperties(); //List<Property> propList = new ArrayList<Property>(); Iterator iKeys = props.keySet().iterator(); ArrayList<String> propertiesToRemove = new ArrayList<String>(); while (iKeys.hasNext()) { String propKey = (String) iKeys.next(); if (propKey.startsWith("registry.custom_lifecycle.votes.") || propKey.startsWith("registry.custom_lifecycle.user.") || propKey.startsWith("registry.custom_lifecycle.checklist.") || propKey.startsWith("registry.LC.name") || propKey.startsWith("registry.lifecycle.") || propKey.startsWith("registry.Aspects")) { propertiesToRemove.add(propKey); } } for (String propertyName : propertiesToRemove) { resource.removeProperty(propertyName); } registry.put(path, resource); } catch (RegistryException e) { String msg = "Failed to remove LifeCycle from resource " + path + ". " + e.getMessage(); log.error(msg, e); throw new RegistryException(msg, e); } } @Deprecated @SuppressWarnings("unused") public static void addSystemCollection(Registry registry, UserRealm userRealm) throws RegistryException { throw new UnsupportedOperationException("This operation is no longer supported."); /*if(log.isTraceEnabled()) { log.trace("Checking the existence of '" + RegistryConstants.SYSTEM_PATH + "' collection of the Registry."); } if (!registry.resourceExists(RegistryConstants.SYSTEM_PATH)) { if (registry.getRegistryContext() != null && registry.getRegistryContext().isClone()) { return; } if(log.isTraceEnabled()) { log.trace("Creating the '" + RegistryConstants.SYSTEM_PATH + "'collection of the Registry."); } CollectionImpl systemCollection = (CollectionImpl) registry.newCollection(); String systemDescription = "System collection of the Registry. This collection is used to store " + "the resources required by the Registry server. It is not recommended to do any modification " + "to this collection."; systemCollection.setDescription(systemDescription); registry.put(RegistryConstants.SYSTEM_PATH, systemCollection); systemCollection.discard(); AuthorizationUtils.denyAnonAuthorization(RegistryConstants.SYSTEM_PATH, userRealm); }*/ } @Deprecated @SuppressWarnings("unused") public static void addCarbonRootCollection(Registry userRegistry, UserRealm userRealm) throws RegistryException { /*if (userRegistry.getRegistryContext() != null && userRegistry.getRegistryContext().isClone()) { return; } String carbonPathParent = System.getProperty(RegistryConstants.CARBON_COLLECTION_PARENT_PROPERTY); String carbonPath; if (carbonPathParent != null) { ResourcePath rootPath = new ResourcePath(carbonPathParent); rootPath.appendPath(RegistryConstants.CARBON_COLLECTION_NAME); carbonPath = rootPath.getPath(); } else { carbonPath = RegistryConstants.ROOT_PATH + RegistryConstants.CARBON_COLLECTION_NAME; } try { if (System.getProperty(RegistryConstants.CARBON_REGISTRY_CLEAN) != null) { // clean the system property to prevent the registry cleanup at the next // restart, if commanded through the admin console, which will carry all the // System properties System.clearProperty(RegistryConstants.CARBON_REGISTRY_CLEAN); if (userRegistry.resourceExists(carbonPath)) { try { userRegistry.delete(carbonPath); log.info("Cleaned the registry space of carbon at path : " + carbonPath); } catch (Exception e) { log.error("An error occurred while cleaning of registry space of carbon " + "at path : " + carbonPath, e); } } } else { if (userRegistry.resourceExists(carbonPath)) { return; } } Collection carbonCollection = userRegistry.newCollection(); String carbonRootDescription = "Root of the system collections used by the Carbon server."; carbonCollection.setDescription(carbonRootDescription); userRegistry.put(carbonPath, carbonCollection); carbonCollection.discard(); AuthorizationUtils.denyAnonAuthorization(carbonPath, userRealm); } catch (Exception e) { String msg = "Unable to setup collections used by the Carbon server."; log.error(msg, e); userRegistry.rollbackTransaction(); throw new RegistryException(e.getMessage(), e); }*/ } @Deprecated @SuppressWarnings("unused") public static void addTenantsCollection(Registry registry, UserRealm userRealm) throws RegistryException { throw new UnsupportedOperationException("This method is no longer supported"); } /** * Method to add the collection where the user profiles are stored. * * @param registry the registry to use. * @param profilesPath the path at which user profiles are stored. * * @throws RegistryException if an error occurred. */ public static void addUserProfileCollection(Registry registry, String profilesPath) throws RegistryException { if (log.isTraceEnabled()) { log.trace("Checking the existence of the '" + profilesPath + "' collection of the Registry."); } if (systemResourceShouldBeAdded(registry, profilesPath)) { if (registry.getRegistryContext() != null && registry.getRegistryContext().isClone()) { return; } if (log.isTraceEnabled()) { log.trace("Creating the '" + profilesPath + "' collection of the Registry."); } CollectionImpl systemCollection = (CollectionImpl) registry.newCollection(); String systemDescription = "Collection which contains user-specific details."; systemCollection.setDescription(systemDescription); registry.put(profilesPath, systemCollection); } } /** * Method to add the collection where the services are stored. * * @param registry the registry to use. * @param servicePath the path at which services are stored. * * @throws RegistryException if an error occurred. */ public static void addServiceStoreCollection(Registry registry, String servicePath) throws RegistryException { if (log.isTraceEnabled()) { log.trace("Checking the existence of the '" + servicePath + "' collection of the Registry."); } if (systemResourceShouldBeAdded(registry, servicePath)) { if (registry.getRegistryContext() != null && registry.getRegistryContext().isClone()) { return; } if (log.isTraceEnabled()) { log.trace("Creating the '" + servicePath + "' collection of the Registry."); } CollectionImpl systemCollection = (CollectionImpl) registry.newCollection(); String systemDescription = "Collection which contains all the Service information"; systemCollection.setDescription(systemDescription); registry.put(servicePath, systemCollection); } } /** * Method to add the collection where the mount information is stored. * * @param registry the registry to use. * * @throws RegistryException if an error occurred. */ public static void addMountCollection(Registry registry) throws RegistryException { if (log.isTraceEnabled()) { log.trace("Checking the existence of the '" + RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH + "' collection of the Registry."); } if (!registry.resourceExists( RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH)) { if (registry.getRegistryContext() != null && registry.getRegistryContext().isClone()) { return; } if (log.isTraceEnabled()) { log.trace("Creating the '" + RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH + "' collection of the Registry."); } Collection mountCollection = registry.newCollection(); String description = "Mount collection stores details of mount points of the registry."; mountCollection.setDescription(description); registry.put(RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH, mountCollection); } } /** * Method to register mount points. * * @param systemRegistry the registry to use. * @param tenantId the identifier of the tenant. * * @throws RegistryException if an error occurred. */ public static void registerMountPoints(Registry systemRegistry, int tenantId) throws RegistryException { String mountPath = RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH; if (!systemRegistry.resourceExists(mountPath)) { return; } CollectionImpl mountCollection = (CollectionImpl) systemRegistry.get(mountPath); String[] mountPoints = mountCollection.getChildren(); Resource mountPoint; for (String mountPointString : mountPoints) { if (!systemRegistry.resourceExists(mountPointString)) { log.warn("Unable to add mount. The mount point " + mountPointString + " was not found."); continue; } mountPoint = systemRegistry.get(mountPointString); if (Boolean.toString(true).equals(mountPoint.getProperty(RegistryConstants.REGISTRY_FIXED_MOUNT))) { continue; } String path = mountPoint.getProperty("path"); String target = mountPoint.getProperty("target"); String targetSubPath = mountPoint.getProperty("subPath"); String author = mountPoint.getProperty("author"); try { CurrentSession.setCallerTenantId(tenantId); if (log.isTraceEnabled()) { log.trace("Creating the mount point. " + "path: " + path + ", " + "target: " + target + ", " + "target sub path " + targetSubPath + "."); } if (targetSubPath != null) { registerHandlerForRemoteLinks(systemRegistry.getRegistryContext(), path, target, targetSubPath, author); } else { registerHandlerForSymbolicLinks(systemRegistry.getRegistryContext(), path, target, author); } } catch (RegistryException e) { log.warn("Couldn't mount " + target + "."); log.debug("Caused by: ", e); } finally { CurrentSession.removeCallerTenantId(); } } } /** * Method to obtain the filter used with the mounting handler. * * @param path the path at which the mount was added. * * @return the built filter instance. */ public static URLMatcher getMountingMatcher(String path) { URLMatcher matcher = new MountingMatcher(path); String matchedWith = Pattern.quote(path) + "($|" + RegistryConstants.PATH_SEPARATOR + ".*|" + RegistryConstants.URL_SEPARATOR + ".*)"; matcher.setPattern(matchedWith); return matcher; } // Sets-up the media types for this instance. public static void setupMediaTypes(RegistryService registryService, int tenantId) { try { Registry registry = registryService.getConfigSystemRegistry(tenantId); MediaTypesUtils.getResourceMediaTypeMappings(registry); MediaTypesUtils.getCustomUIMediaTypeMappings(registry); MediaTypesUtils.getCollectionMediaTypeMappings(registry); } catch (RegistryException e) { log.error("Unable to create fixed remote mounts.", e); } } // Do tenant-specific initialization. public static void initializeTenant(RegistryService registryService, int tenantId) throws RegistryException { try { UserRegistry systemRegistry = registryService.getConfigSystemRegistry(); if (systemRegistry.getRegistryContext() != null) { HandlerManager handlerManager = systemRegistry.getRegistryContext().getHandlerManager(); if (handlerManager instanceof HandlerLifecycleManager) { ((HandlerLifecycleManager) handlerManager).init(tenantId); } } systemRegistry = registryService.getRegistry(CarbonConstants.REGISTRY_SYSTEM_USERNAME, tenantId); addMountCollection(systemRegistry); registerMountPoints(systemRegistry, tenantId); new RegistryCoreServiceComponent().setupMounts(registryService, tenantId); setupMediaTypes(registryService, tenantId); // We need to set the tenant ID for current session. Otherwise the // underlying operations fails try { CurrentSession.setTenantId(tenantId); RegistryContext registryContext = systemRegistry.getRegistryContext(); // Adding collection to store user profile information. addUserProfileCollection(systemRegistry, getAbsolutePath(registryContext, registryContext.getProfilesPath())); // Adding collection to store services. addServiceStoreCollection(systemRegistry, getAbsolutePath(registryContext, registryContext.getServicePath())); // Adding service configuration resources. addServiceConfigResources(systemRegistry); } finally { CurrentSession.removeTenantId(); } } catch (RegistryException e) { log.error("Unable to initialize registry for tenant " + tenantId + ".", e); throw new RegistryException("Unable to initialize registry for tenant " + tenantId + ".", e); } } // This class is used to implement a URL Matcher that could be used for Mounting related // handlers. private static class MountingMatcher extends URLMatcher { private boolean isExecuteQueryAllowed; public MountingMatcher(String path) { RegistryContext registryContext = RegistryContext.getBaseInstance(); for (Mount mount : registryContext.getMounts()) { if (path.equals(mount.getPath())) { isExecuteQueryAllowed = mount.isExecuteQueryAllowed(); break; } } } // Mounting related handlers support execute query for any path. public boolean handleExecuteQuery(RequestContext requestContext) throws RegistryException { return isExecuteQueryAllowed; } // Mounting related handlers support get resource paths with tag for any path. public boolean handleGetResourcePathsWithTag(RequestContext requestContext) throws RegistryException { return true; } } /** * Utility method obtain the list of operations supported by the mount handler. * * @return the list of operations. */ public static String[] getMountingMethods() { return new String[] { Filter.RESOURCE_EXISTS, Filter.GET, Filter.PUT, Filter.DELETE, Filter.RENAME, Filter.MOVE, Filter.COPY, Filter.GET_AVERAGE_RATING, Filter.GET_RATING, Filter.RATE_RESOURCE, Filter.GET_COMMENTS, Filter.ADD_COMMENT, Filter.EDIT_COMMENT, Filter.REMOVE_COMMENT, Filter.GET_TAGS, Filter.APPLY_TAG, Filter.REMOVE_TAG, Filter.GET_ALL_ASSOCIATIONS, Filter.GET_ASSOCIATIONS, Filter.ADD_ASSOCIATION, Filter.DUMP, Filter.RESTORE, Filter.REMOVE_ASSOCIATION, Filter.IMPORT, Filter.EXECUTE_QUERY, Filter.GET_RESOURCE_PATHS_WITH_TAG, Filter.GET_REGISTRY_CONTEXT, Filter.REMOVE_LINK }; } /** * Method to add the resources where the service configuration are stored. * * @param registry the registry to use. * * @throws RegistryException if an error occurred. */ public static void addServiceConfigResources(Registry registry) throws RegistryException { try { boolean inTransaction = Transaction.isStarted(); if (!inTransaction) { registry.beginTransaction(); } ServiceConfigUtil.addConfig(registry); //add the resource service in to /governance/configuration/ ServiceConfigUtil.addConfigSchema(registry); if (!inTransaction) { registry.commitTransaction(); } } catch (Exception e) { String msg = "Unable to setup service configuration."; log.error(msg, e); registry.rollbackTransaction(); throw new RegistryException(e.getMessage(), e); } } /** * Method to concatenate two chroot paths. * * @param chroot1 the base chroot path (or the registry root). * @param chroot2 the the relative chroot path. * * @return the full chroot path. */ public static String concatenateChroot(String chroot1, String chroot2) { String chroot1out = chroot1; if (chroot1out == null || chroot1out.equals(RegistryConstants.ROOT_PATH)) { return chroot2; } if (chroot2 == null || chroot2.equals(RegistryConstants.ROOT_PATH)) { return chroot1out; } if (!chroot1out.endsWith(RegistryConstants.PATH_SEPARATOR) && !chroot2.startsWith(RegistryConstants.PATH_SEPARATOR)) { chroot1out += RegistryConstants.PATH_SEPARATOR; } else if (chroot1out.endsWith(RegistryConstants.PATH_SEPARATOR) && chroot2.startsWith(RegistryConstants.PATH_SEPARATOR)) { chroot1out = chroot1out.substring(0, chroot1out.length() - 1); } String chroot = chroot1out + chroot2; if (chroot.endsWith(RegistryConstants.PATH_SEPARATOR)) { chroot = chroot.substring(0, chroot.length() - 1); } return chroot; } /** * Method to determine whether this registry is running in Read-Only mode. * * @param registryContext the registry context. * * @return true if read-only or false otherwise. */ public static boolean isRegistryReadOnly(RegistryContext registryContext) { String repositoryWriteModeProperty = System.getProperty(ServerConstants.REPO_WRITE_MODE); if (repositoryWriteModeProperty != null) { return !(repositoryWriteModeProperty.equals("true")); } ServerConfiguration serverConfig = CarbonUtils.getServerConfiguration(); String isRegistryReadOnly = serverConfig.getFirstProperty("Registry.ReadOnly"); if (isRegistryReadOnly == null) { if (registryContext != null) { return registryContext.isReadOnly(); } return RegistryContext.getBaseInstance().isReadOnly(); } return isRegistryReadOnly.equalsIgnoreCase(Boolean.TRUE.toString()); } /** * this method can only be called if the registry context is initialized. * * @param coreRegistry the core registry instance. * * @return the user registry instance for the special system user. * @throws RegistryException if the operation failed. */ public static Registry getSystemRegistry(Registry coreRegistry) throws RegistryException { RealmService realmService = coreRegistry.getRegistryContext().getRealmService(); String systemUser = CarbonConstants.REGISTRY_SYSTEM_USERNAME; if (systemUser.equals(CurrentSession.getUser())) { return CurrentSession.getUserRegistry(); } return new UserRegistry(systemUser, CurrentSession.getTenantId(), coreRegistry, realmService, CurrentSession.getChroot(), true); } /** * This method returns the bootstrap (or initial) user realm. You can call this function only if * the registry context is initialized * * @return the bootstrap realm. * @throws RegistryException if the operation failed. */ @Deprecated @SuppressWarnings("unused") public static UserRealm getBootstrapRealm() throws RegistryException { RegistryContext registryContext = RegistryContext.getBaseInstance(); if (registryContext == null) { String msg = "Registry context is null. Failed to get the registry context."; log.error(msg); throw new RegistryException(msg); } if (registryContext.getRealmService() == null) { String msg = "Error in getting the bootstrap realm. " + "The realm service is not available."; log.error(msg); throw new RegistryException(msg); } try { UserRealm realm = registryContext.getRealmService().getBootstrapRealm(); return new RegistryRealm(realm); } catch (Exception e) { String msg = "Error in getting the user realm for main tenant."; log.error(msg); throw new RegistryException(msg, e); } } /** * Method to record statistics. * * @param parameters The parameters to be passed to the statistics collector interface. * Generally, it is expected that each method invoking this method will pass * all relevant parameters such that the statistics collectors can examine * them as required. */ @SuppressWarnings("unused") // This method is used in Components. public static void recordStatistics(Object... parameters) { StatisticsCollector[] statisticsCollectors = RegistryContext.getBaseInstance().getStatisticsCollectors(); for (StatisticsCollector collector : statisticsCollectors) { collector.collect(parameters); } } /** * This method returns the bootstrap (or initial) user realm from the realm service. * * @param realmService the OSGi service which we can use to obtain the user realm. * * @return the bootstrap realm. * @throws RegistryException if the operation failed. */ public static UserRealm getBootstrapRealm(RealmService realmService) throws RegistryException { try { UserRealm realm = realmService.getBootstrapRealm(); return new RegistryRealm(realm); } catch (Exception e) { String msg = "Error in getting the user realm for main tenant."; log.error(msg); throw new RegistryException(msg, e); } } /** * Method to obtain the unchrooted path for the given relative path. * * @param path the relative path. * * @return the unchrooted path. */ public static String getUnChrootedPath(String path) { if (path == null) { return null; } String localPath = path; if (CurrentSession.getLocalPathMap() != null) { String temp = CurrentSession.getLocalPathMap().get(path); if (temp != null) { localPath = temp; } } if (CurrentSession.getUserRealm() != null) { // we are already checking the unchrooted paths, so no more work return localPath; } String chrootPrefix = getChrootPrefix(); if (chrootPrefix == null) { // no chroot defined or it equals to root. return localPath; } else if (!localPath.startsWith("/")) { // not a registry resource return localPath; } else if (localPath.equals("/")) { return chrootPrefix; } // Relative path, so prepend basePrefix appropriately return chrootPrefix + localPath; } // method to obtain chroot prefix. private static String getChrootPrefix() { RegistryContext registryContext = RegistryContext.getBaseInstance(); if (registryContext == null) { // adding non-path resources at the start-up return null; } String chrootPrefix = registryContext.getRegistryRoot(); if (chrootPrefix == null || chrootPrefix.length() == 0 || chrootPrefix.equals(RegistryConstants.ROOT_PATH)) { return null; } return chrootPrefix; } /** * Method to obtain the relative path for the given absolute path. * * @param context the registry context. * @param absolutePath the absolute path. * * @return the relative path. */ public static String getRelativePath(RegistryContext context, String absolutePath) { if (context == null) { return getRelativePathToOriginal(absolutePath, RegistryContext.getBaseInstance().getRegistryRoot()); } return getRelativePathToOriginal(absolutePath, context.getRegistryRoot()); } /** * Method to obtain the absolute path for the given relative path. * * @param context the registry context. * @param relativePath the relative path. * * @return the absolute path. */ public static String getAbsolutePath(RegistryContext context, String relativePath) { if (context == null) { return getAbsolutePathToOriginal(relativePath, RegistryContext.getBaseInstance().getRegistryRoot()); } return getAbsolutePathToOriginal(relativePath, context.getRegistryRoot()); } /** * Method to obtain the path relative to the given path. * * @param absolutePath the absolute path. * @param originalPath the path to which we need to make the given absolute path a relative * one. * * @return the relative path. */ public static String getRelativePathToOriginal(String absolutePath, String originalPath) { // the relative path of a path that is null, will be null if (absolutePath == null) { return null; } if (!absolutePath.startsWith("/")) { // we can consider this is not a path return absolutePath; } // No worries if there's no original path if (originalPath == null || originalPath.length() == 0 || originalPath.equals("/")) { return absolutePath; } if (originalPath.equals(absolutePath)) { return "/"; } if (absolutePath.startsWith(originalPath)) { return absolutePath.substring(originalPath.length()); } // Somewhere else, so make sure there are dual slashes at the beginning return "/" + absolutePath; } /** * Method to obtain the path absolute to the given path. * * @param relativePath the relative path. * @param originalPath the path to which we need to make the given relative path a absolute * one. * * @return the absolute path. */ public static String getAbsolutePathToOriginal(String relativePath, String originalPath) { // the absolute path of a path that is null, will be null if (relativePath == null) { return null; } if (!relativePath.startsWith("/")) { // we can consider this is not a path return relativePath; } // No worries if there's no original path if (originalPath == null || originalPath.length() == 0 || originalPath.equals("/")) { return relativePath; } if (relativePath.startsWith("//")) { // the path is outside the scope of the original path, so return absolute path removing // the first '/' return relativePath.substring(1); } // then it is the concatenate that make the absolute path return originalPath + relativePath; } /** * Method to register handlers for symbolic links for the tenant on the current registry * session. * * @param context the registry context. * @param path the path at which the symbolic link is created. * @param target the target path. * @param author the creator of the symbolic link. * * @throws RegistryException if the operation failed. */ public static void registerHandlerForSymbolicLinks(RegistryContext context, String path, String target, String author) throws RegistryException { SymLinkHandler handler = new SymLinkHandler(); handler.setMountPoint(path); handler.setTargetPoint(target); handler.setAuthor(author); HandlerManager hm = context.getHandlerManager(); hm.addHandler(RegistryUtils.getMountingMethods(), RegistryUtils.getMountingMatcher(path), handler, HandlerLifecycleManager.TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE); // now we are going to iterate through all the already available symbolic links and resolve // the cyclic symbolic links Set<SymLinkHandler> symLinkHandlers = SymLinkHandler.getSymLinkHandlers(); List<SymLinkHandler> handlersToRemove = new ArrayList<SymLinkHandler>(); for (SymLinkHandler symLinkHandler : symLinkHandlers) { String symLinkTarget = symLinkHandler.getTargetPoint(); // and then we remove old entries for the same mount path String mountPath = symLinkHandler.getMountPoint(); if (path.equals(mountPath) && !target.equals(symLinkTarget)) { handlersToRemove.add(symLinkHandler); } } // removing the symlink handlers for (SymLinkHandler handlerToRemove : handlersToRemove) { hm.removeHandler(handlerToRemove, HandlerLifecycleManager.TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE); } // and importantly add the new entry, the currently creating symlink information.. symLinkHandlers.add(handler); } /** * Method to register handlers for remote links for the tenant on the current registry session. * * @param registryContext the registry context. * @param path the path at which the remote link is created. * @param target the target path. * @param targetSubPath the target sub-path. * @param author the creator of the remote link. * * @throws RegistryException if the operation failed. */ public static void registerHandlerForRemoteLinks(RegistryContext registryContext, String path, String target, String targetSubPath, String author) throws RegistryException { registerHandlerForRemoteLinks(registryContext, path, target, targetSubPath, author, false); } /** * Method to register handlers for remote links. * * @param registryContext the registry context. * @param path the path at which the remote link is created. * @param target the target path. * @param targetSubPath the target sub-path. * @param author the creator of the remote link. * @param forAllTenants whether the remote link should be added to the tenant on the current * registry session or to all the tenants. * * @throws RegistryException if the operation failed. */ public static void registerHandlerForRemoteLinks(RegistryContext registryContext, String path, String target, String targetSubPath, String author, boolean forAllTenants) throws RegistryException { HandlerManager hm = registryContext.getHandlerManager(); List<RemoteConfiguration> remoteInstances = registryContext.getRemoteInstances(); for (RemoteConfiguration config : remoteInstances) { if (config.getId().equals(target)) { MountHandler handler = new MountHandler(); handler.setUserName(config.getTrustedUser()); handler.setPassword(config.getResolvedTrustedPwd()); handler.setDbConfig(config.getDbConfig()); handler.setRegistryRoot(config.getRegistryRoot()); handler.setReadOnly(config.getReadOnly() != null && Boolean.toString(true).equals(config.getReadOnly().toLowerCase())); handler.setId(target); handler.setConURL(config.getUrl()); handler.setMountPoint(path); handler.setSubPath(targetSubPath); handler.setAuthor(author); if (config.getTrustedUser() == null || config.getTrustedPwd() == null) { handler.setRemote(false); } else { handler.setRemote(true); handler.setRegistryType(config.getType()); } if (forAllTenants) { hm.addHandler(RegistryUtils.getMountingMethods(), RegistryUtils.getMountingMatcher(path), handler); } else { hm.addHandler(RegistryUtils.getMountingMethods(), RegistryUtils.getMountingMatcher(path), handler, HandlerLifecycleManager.TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE); } return; } } // We will get here, if somebody checks in to a remote registry with a no mount paths. // Such information ends up in our debug logs. if (remoteInstances.size() == 0) { String msg = "No remote instances have been found, " + "The following mount point is not registered. " + "path: " + path + ", " + "target: " + target + ", " + ((targetSubPath == null) ? "" : ("target sub path: " + targetSubPath + ", ")); log.debug(msg); } else { String msg = "Target mount path is not found, " + "The following mount point is not registered. " + "path: " + path + ", " + "target: " + target + ", " + ((targetSubPath == null) ? "" : ("target sub path: " + targetSubPath + ", ")); log.debug(msg); } } /** * Method to add a mount entry. * * @param registry the registry instance to use. * @param registryContext the registry context. * @param path the source path. * @param target the target path or instance. * @param targetSubPath the target sub-path. * @param author the author * * @throws RegistryException if the operation failed. */ public static void addMountEntry(Registry registry, RegistryContext registryContext, String path, String target, String targetSubPath, String author) throws RegistryException { Resource r = new ResourceImpl(); String relativePath = RegistryUtils.getRelativePath(registryContext, path); r.addProperty("path", relativePath); r.addProperty("target", target); r.addProperty("author", author); r.addProperty("subPath", targetSubPath); r.setMediaType(RegistryConstants.MOUNT_MEDIA_TYPE); String mountPath = RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH + "/" + relativePath.replace("/", "-"); if (!registry.resourceExists(mountPath)) { registry.put(mountPath, r); } } /** * Method to add a mount entry. * * @param registry the registry instance to use. * @param registryContext the registry context. * @param path the source path. * @param target the target path or instance. * @param remote whether local or remote link. * @param author the author * * @throws RegistryException if the operation failed. */ public static void addMountEntry(Registry registry, RegistryContext registryContext, String path, String target, boolean remote, String author) throws RegistryException { //persist mount details Resource r = new ResourceImpl(); String relativePath; if (remote) { relativePath = path; } else { relativePath = RegistryUtils.getRelativePath(registryContext, path); } r.addProperty("path", relativePath); r.addProperty("target", RegistryUtils.getRelativePath(registryContext, target)); r.addProperty("author", author); r.setMediaType(RegistryConstants.MOUNT_MEDIA_TYPE); String mountPath = RegistryConstants.LOCAL_REPOSITORY_BASE_PATH + RegistryConstants.SYSTEM_MOUNT_PATH + "/" + relativePath.replace("/", "-"); if (!registry.resourceExists(mountPath)) { registry.put(mountPath, r); } } /** * Gets the resource with sufficient data to differentiate it from another resource. This would * populate a {@link ResourceImpl} with the <b>path</b>, <b>name</b> and <b>path identifier</b> * of a resource. * * @param path the path of the resource. * @param resourceDAO the resource data access object to use. * @param versioned whether version or not. * * @return the resource with minimum data. * @throws RegistryException if an error occurs while retrieving resource data. */ public static ResourceImpl getResourceWithMinimumData(String path, ResourceDAO resourceDAO, boolean versioned) throws RegistryException { ResourceIDImpl resourceID = resourceDAO.getResourceID(path); if (resourceID == null) { return null; } ResourceImpl resourceImpl; if (resourceID.isCollection()) { resourceImpl = new CollectionImpl(); } else { resourceImpl = new ResourceImpl(); } if (versioned) { resourceImpl.setVersionNumber(resourceDAO.getVersion(resourceID)); } else { resourceImpl.setName(resourceID.getName()); resourceImpl.setPathID(resourceID.getPathID()); } resourceImpl.setPath(path); return resourceImpl; } /** * Calculate the relative associations path to the reference path if an absolute path is given. * This is used in dump. * * @param path absolute path value. * @param referencePath the reference path * * @return the relative path */ public static String getRelativeAssociationPath(String path, String referencePath) { //StringTokenizer basePathTokenizer = new StringTokenizer(referencePath); String[] referencePathParts = referencePath.split("/"); String[] pathParts = path.split("/"); int i; for (i = 0; i < referencePathParts.length - 1 && i < pathParts.length - 1; i++) { if (!referencePathParts[i].equals(pathParts[i])) { break; } } StringBuilder prefix = new StringBuilder(); int j = i; for (; i < referencePathParts.length - 1; i++) { prefix.append("../"); } for (; j < pathParts.length - 1; j++) { prefix.append(pathParts[j]).append("/"); } String relPath; if (pathParts.length != 0) { relPath = prefix.append(pathParts[j]).toString(); } else { relPath = path; //For the root("/") associations } while (relPath.contains("//")) { relPath = relPath.replaceAll("//", "/../"); // in case "//" is found. } return relPath; } /** * Calculate the absolute associations path if a relative path is given to the reference path. * This works only ".." components are there at the very start. This is used in restore. * * @param path relative path value. * @param referencePath the reference path * * @return the absolute path */ public static String getAbsoluteAssociationPath(String path, String referencePath) { //StringTokenizer basePathTokenizer = new StringTokenizer(referencePath); String[] referencePathParts = referencePath.split("/"); String[] pathParts = path.split("/"); int i; // here the limit of going up = referencePathParts.length - 2 // (excluding "" component and resource name) for (i = 0; i < referencePathParts.length - 2 && i < pathParts.length; i++) { if (!pathParts[i].equals("..")) { break; } } int goUps = i; StringBuilder absolutePath = new StringBuilder(); // we are checking whether the path parts have more .. beyond the reference paths reach for (; i < pathParts.length; i++) { if (pathParts[i].equals("..")) { absolutePath.append("/"); } else { break; } } int remainLen = i; for (i = 0; i < referencePathParts.length - goUps - 1; i++) { absolutePath.append(referencePathParts[i]).append("/"); } // from that onwards we collecting path parts. for (i = remainLen; i < pathParts.length - 1; i++) { absolutePath.append(pathParts[i]).append("/"); } return absolutePath.append(pathParts[pathParts.length - 1]).toString(); } /** * Load the class with the given name * * @param name name of the class * * @return java class * @throws ClassNotFoundException if the class does not exists in the classpath */ public static Class loadClass(String name) throws ClassNotFoundException { try { return Class.forName(name); } catch (ClassNotFoundException e) { File extensionLibDirectory = new File(RegistryUtils.getExtensionLibDirectoryPath()); if (extensionLibDirectory.exists() && extensionLibDirectory.isDirectory()) { File[] files = extensionLibDirectory.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return name != null && name.endsWith(".jar"); } }); if (files != null && files.length > 0) { List<URL> urls = new ArrayList<URL>(files.length); for (File file : files) { try { urls.add(file.toURI().toURL()); } catch (MalformedURLException ignore) { } } ClassLoader origTCCL = Thread.currentThread().getContextClassLoader(); try { ClassLoader cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), RegistryUtils.class.getClassLoader()); return cl.loadClass(name); } finally { Thread.currentThread().setContextClassLoader(origTCCL); } } } throw e; } } /** * Method to determine whether a property is a hidden property or not. * @param propertyName the name of property. * @return true if the property is a hidden property or false if not. */ public static boolean isHiddenProperty(String propertyName) { return propertyName.startsWith("registry."); } public static String getExtensionLibDirectoryPath() { CarbonContext carbonContext = CarbonContext.getThreadLocalCarbonContext(); int tempTenantId = carbonContext.getTenantId(); return ((tempTenantId != MultitenantConstants.INVALID_TENANT_ID && tempTenantId != MultitenantConstants.SUPER_TENANT_ID) ? (CarbonUtils.getCarbonTenantsDirPath() + File.separator + carbonContext.getTenantId()) : (CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "deployment" + File.separator + "server")) + File.separator + "registryextensions"; } public static String decodeBytes(byte[] byteContent) throws RegistryException { String co; try { if (ENCODING == null) { co = new String(byteContent); } else { co = new String(byteContent, ENCODING); } } catch (UnsupportedEncodingException e) { String msg = ENCODING + " is unsupported encoding type"; log.error(msg, e); throw new RegistryException(msg, e); } return co; } public static byte[] encodeString(String content) throws RegistryException { byte[] bytes; try { if (ENCODING == null) { bytes = content.getBytes(); } else { bytes = content.getBytes(ENCODING); } } catch (UnsupportedEncodingException e) { String msg = ENCODING + " is unsupported encoding type"; log.error(msg, e); throw new RegistryException(msg, e); } return bytes; } }