| /* |
| * 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(); |
| } |
| |
| } |