/*
* Copyright (c) 2005-2012, 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.extensions.handlers;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Map.Entry;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.jdbc.handlers.RequestContext;
import org.wso2.carbon.registry.core.jdbc.handlers.Handler;
/**
* This handler implementation handles the delete process of services, collections and resources with Subscriptions.
*/
public class DeleteSubscriptionHandler extends Handler {
private static final String TOPIC_INDEX_PATH = "/_system/governance/event/topicIndex";
private static final String SUBSCRIPTION_PATH_PREFIX = "/_system/governance/event/topics/registry/notifications";
private static final String NOTIFICATION_PREFIX = "/registry/notifications";
private static final String WS_SUBSCRIPTION = "ws.subscriptions";
public void delete(RequestContext requestContext) throws RegistryException {
if(!isDeleteLockAvailable()){
return;
}
acquireDeleteLock();
try {
String deletedResourcePath = requestContext.getResourcePath().getPath();
final Registry registry = requestContext.getRegistry();
Resource resource = registry.getMetaData(deletedResourcePath);
boolean isCollection = false;
if (resource.getMediaType() == null) {
isCollection = true;
}
if (!registry.resourceExists(TOPIC_INDEX_PATH)) {
return;
}
Resource topicIndexResource = registry.get(TOPIC_INDEX_PATH);
Properties properties = topicIndexResource.getProperties();
List<String> propertiesToDelete = new ArrayList<String>();
List<String> pathsToDelete = new ArrayList<String>();
Iterator<?> iterator = properties.entrySet().iterator();
while(iterator.hasNext()) {
Entry<String, List<String>> entry = (Entry<String, List<String>>) iterator.next();
if (entry.getValue().size() > 1) {
throw new RegistryException("Multiple properties available for same UUID.");
}
String pathArry = entry.getValue().get(0);
if (!pathArry.startsWith(NOTIFICATION_PREFIX)) {
continue;
}
String propertyPath = pathArry.substring(NOTIFICATION_PREFIX.length());
String absPropPath = propertyPath.substring(1).substring(propertyPath.substring(1).indexOf("/"));
if (deletedResourcePath.equalsIgnoreCase(absPropPath)) {
String key = entry.getKey();
if (!propertiesToDelete.contains(key)) {
propertiesToDelete.add(key);
}
if (!isCollection) {
String firstPath = propertyPath.substring(0, propertyPath.lastIndexOf("/"));
String lastPath = propertyPath.substring(propertyPath.lastIndexOf("/") + 1);
if (lastPath.lastIndexOf(".") != -1) {
String fileName = lastPath.substring(0, lastPath.lastIndexOf("."));
String extension = lastPath.substring(lastPath.lastIndexOf(".") + 1);
StringBuffer sb = new StringBuffer();
sb.append(firstPath).append("/").append(fileName).append("/").append(extension);
propertyPath = sb.toString();
}
}
String pathToDelete = SUBSCRIPTION_PATH_PREFIX + propertyPath.replaceAll("\\.", "/");
StringBuffer sb = new StringBuffer();
sb.append(pathToDelete).append("/").append(WS_SUBSCRIPTION).append("/").append(key);
pathToDelete = sb.toString();
if (!pathsToDelete.contains(pathToDelete)) {
pathsToDelete.add(pathToDelete);
}
}
}
for (String property : propertiesToDelete) {
topicIndexResource.removeProperty(property);
registry.put(TOPIC_INDEX_PATH, topicIndexResource);
}
for (String path: pathsToDelete) {
if(registry.resourceExists(path)) {
registry.delete(path);
}
}
} finally {
releaseDeleteLock();
}
}
private static ThreadLocal<Boolean> deleteInProgress = new ThreadLocal<Boolean>() {
protected Boolean initialValue() {
return false;
}
};
public static boolean isDeleteLockAvailable() {
return !deleteInProgress.get();
}
public static void acquireDeleteLock() {
deleteInProgress.set(true);
}
public static void releaseDeleteLock() {
deleteInProgress.set(false);
}
}