blob: 483deab87dea6502c9139bcce04c0f190cbee3f2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.sling.cassandra.resource.provider;
import me.prettyprint.cassandra.model.CqlRows;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.beans.Row;
import me.prettyprint.hector.api.query.QueryResult;
import org.apache.sling.adapter.annotations.Adaptable;
import org.apache.sling.adapter.annotations.Adapter;
import org.apache.sling.api.resource.*;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.cassandra.resource.provider.mapper.CassandraMapperException;
import org.apache.sling.cassandra.resource.provider.util.CassandraResourceProviderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
@Adaptable(adaptableClass=Resource.class, adapters={
@Adapter({ValueMap.class})
})
public class CassandraResource extends AbstractResource {
private String resourcePath;
private String remainingPath;
private String columnFamilySector;
private CassandraResourceProvider resourceProvider;
private ResourceResolver resourceResolver;
private static Logger LOGGER = LoggerFactory.getLogger(CassandraResource.class);
private boolean dataLoaded = false;
private String resourceSuperType = "nt:supCassandra";
private String resourceType = "nt:casandra";
private String metadata = "resolutionPathInfo=json";
private final ValueMap valueMap;
private boolean isTransient = false;
static class CassandraValueMap extends ValueMapDecorator {
CassandraValueMap(String path) {
super(new HashMap<String, Object>());
put("path", path);
}
}
public CassandraResource(ResourceProvider resourceProvider, ResourceResolver resourceResolver, String resourcePath,ValueMap valueMap) {
this.resourceProvider = (CassandraResourceProvider) resourceProvider;
this.resourceResolver = resourceResolver;
this.resourcePath = resourcePath;
this.remainingPath = CassandraResourceProviderUtil.getRemainingPath(resourcePath);
this.columnFamilySector = CassandraResourceProviderUtil.getColumnFamilySector(resourcePath);
this.valueMap = valueMap;
}
public CassandraResource(ResourceProvider resourceProvider, ResourceResolver resourceResolver, String resourcePath,ValueMap valueMap,Map<String, Object> stringObjectMap) {
this.resourceProvider = (CassandraResourceProvider) resourceProvider;
this.resourceResolver = resourceResolver;
this.resourcePath = resourcePath;
this.remainingPath = CassandraResourceProviderUtil.getRemainingPath(resourcePath);
this.columnFamilySector = CassandraResourceProviderUtil.getColumnFamilySector(resourcePath);
this.valueMap = valueMap;
this.isTransient = true;
// this.metadata=stringObjectMap.get("metadata").toString();
// this.resourceType=stringObjectMap.get("resourceType").toString();
// this.resourceSuperType=stringObjectMap.get("resourceSuperType").toString();
}
private void loadResourceData(ResourceProvider resourceProvider) {
CassandraResourceProvider cassandraResourceProvider = (CassandraResourceProvider) resourceProvider;
try {
// TODO ColumnFamilySector is NULL and hence this..
String cql = cassandraResourceProvider.getCassandraMapperMap().get(columnFamilySector).getCQL(columnFamilySector, remainingPath);
QueryResult<CqlRows<String, String, String>> results = CassandraResourceProviderUtil.executeQuery(cql, ((CassandraResourceProvider) resourceProvider).getKeyspace(), new StringSerializer());
populateDataFromResult(results);
dataLoaded = true;
} catch (CassandraMapperException e) {
System.out.println("Error occurred from resource at " + resourcePath + " : " + e.getMessage());
LOGGER.error("Error occurred from resource at " + resourcePath + " : " + e.getMessage());
}
}
private void populateDataFromResult(QueryResult<CqlRows<String, String, String>> result) {
for (Row<String, String, String> row : result.get().getList()) {
for (HColumn column : row.getColumnSlice().getColumns()) {
// Assumed Only one result, since key is unique
if (column.getName().equals("metadata")) {
this.metadata = column.getValue().toString();
} else if (column.getName().equals("resourceSuperType")) {
this.resourceSuperType = column.getValue().toString();
} else if (column.getName().equals("resourceType")) {
this.resourceType = column.getValue().toString();
}
}
}
}
public String getPath() {
return resourcePath;
}
@Override
public String getName() {
return CassandraResourceProviderUtil.getNameFromPath(resourcePath);
}
@Override
public Resource getParent() {
return new CassandraResource(this.resourceProvider,
this.resourceResolver,
CassandraResourceProviderUtil.getParentPath(resourcePath),valueMap);
}
@Override
public Iterator<Resource> listChildren() {
List<Resource> children = new ArrayList<Resource>();
try {
QueryResult<CqlRows<String, String, String>> result = CassandraResourceProviderUtil.getAllNodes(
resourceProvider.getKeyspace(),
CassandraResourceProviderUtil.getColumnFamilySector(resourcePath));
for (Row<String, String, String> row : result.get().getList()) {
for (HColumn column : row.getColumnSlice().getColumns()) {
if ("path".equals(column.getName()) && CassandraResourceProviderUtil.isAnImmediateChild(resourcePath, column.getValue().toString())) {
children.add( new CassandraResource(resourceProvider,resourceResolver,column.getValue().toString(),valueMap));
}
}
}
} catch (Exception e) {
System.out.println("Error occurred while getting child nodes " + e.getMessage());
LOGGER.error("Error occurred while getting child nodes " + e.getMessage());
}
return children.iterator();
}
@Override
public Iterable<Resource> getChildren() {
return new CassandraIterable(listChildren());
}
@Override
public Resource getChild(String s) {
return resourceProvider.getResource(resourceResolver,new StringBuilder(resourcePath.endsWith("/") ? resourcePath.substring(0, resourcePath.length() - 1)
: resourcePath)
.append("/").append(s).toString());
// return new CassandraResource(
// this.resourceProvider,
// this.resourceResolver,
// new StringBuilder(resourcePath.endsWith("/") ? resourcePath.substring(0, resourcePath.length() - 1)
// : resourcePath)
// .append("/").append(s).toString(),valueMap);
}
public String getResourceType() {
if(!isTransient) {
loadResourceData(resourceProvider);
}
return this.resourceType;
}
public String getResourceSuperType() {
if(!isTransient) {
loadResourceData(resourceProvider);
}
return this.resourceSuperType;
}
@Override
public boolean isResourceType(String s) {
return super.isResourceType(s);
}
public ResourceMetadata getResourceMetadata() {
if(!isTransient) {
loadResourceData(resourceProvider);
}
// Expected format of metadata is a String; i.e "characterEncoding=UTF-8,resolutionPathInfo=.html"
if(metadata == null || "".equals(metadata) || metadata.split(",").length == 0) {
ResourceMetadata resourceMetadata = new ResourceMetadata();
resourceMetadata.setModificationTime(System.currentTimeMillis());
resourceMetadata.setResolutionPath(resourcePath);
return resourceMetadata;
}
ResourceMetadata resourceMetadata = new ResourceMetadata();
for(String ele:metadata.split(",")) {
String key=ele.split("=")[0].trim();
String value=ele.split("=")[1].trim();
if("characterEncoding".equalsIgnoreCase(key)) {
resourceMetadata.setCharacterEncoding(value);
} else if("contentType".equalsIgnoreCase(key)) {
resourceMetadata.setContentType(value);
} else if("contentLength".equalsIgnoreCase(key)) {
resourceMetadata.setContentLength(Integer.valueOf(value));
} else if("resolutionPathInfo".equalsIgnoreCase(key)) {
resourceMetadata.setResolutionPathInfo(value);
}
}
resourceMetadata.setModificationTime(System.currentTimeMillis());
resourceMetadata.setResolutionPath(resourcePath);
return resourceMetadata;
}
public ResourceResolver getResourceResolver() {
return this.resourceResolver;
}
@Override
@SuppressWarnings("unchecked")
public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
if(type == ValueMap.class) {
return (AdapterType)valueMap;
} else if (type == ModifiableValueMap.class) {
return (AdapterType)valueMap;
}
return super.adaptTo(type);
}
@Override
public String toString(){
return new StringBuilder("{\nresourcePath=").append(resourcePath).
append("\n remainingPath=").append(remainingPath).
append("\n columnFamilySector=").append(columnFamilySector).
append("\n resourceSuperType=").append(resourceSuperType).
append("\n resourceType=").append(resourceType).
append("\n metaData=").append(metadata).append("\n}").toString();
}
}