001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.component; 018 019import java.io.ByteArrayInputStream; 020import java.io.IOException; 021import java.io.InputStream; 022 023import org.apache.camel.Component; 024import org.apache.camel.api.management.ManagedAttribute; 025import org.apache.camel.api.management.ManagedOperation; 026import org.apache.camel.api.management.ManagedResource; 027import org.apache.camel.api.management.mbean.ManagedResourceEndpointMBean; 028import org.apache.camel.converter.IOConverter; 029import org.apache.camel.impl.ProcessorEndpoint; 030import org.apache.camel.spi.Metadata; 031import org.apache.camel.spi.UriParam; 032import org.apache.camel.spi.UriPath; 033import org.apache.camel.util.IOHelper; 034import org.apache.camel.util.ResourceHelper; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038/** 039 * A useful base class for endpoints which depend on a resource 040 * such as things like Velocity or XQuery based components. 041 */ 042@ManagedResource(description = "Managed ResourceEndpoint") 043public abstract class ResourceEndpoint extends ProcessorEndpoint implements ManagedResourceEndpointMBean { 044 protected final Logger log = LoggerFactory.getLogger(getClass()); 045 private volatile byte[] buffer; 046 @UriPath(description = "Path to the resource, or a reference to lookup a bean in the Registry to use as the resource") @Metadata(required = "true") 047 private String resourceUri; 048 @UriParam(defaultValue = "false", description = "Sets whether to use resource content cache or not") 049 private boolean contentCache; 050 051 public ResourceEndpoint() { 052 } 053 054 public ResourceEndpoint(String endpointUri, Component component, String resourceUri) { 055 super(endpointUri, component); 056 this.resourceUri = resourceUri; 057 } 058 059 /** 060 * Gets the resource as an input stream considering the cache flag as well. 061 * <p/> 062 * If cache is enabled then the resource content is cached in an internal buffer and this content is 063 * returned to avoid loading the resource over and over again. 064 * 065 * @return the input stream 066 * @throws IOException is thrown if error loading the content of the resource to the local cache buffer 067 */ 068 public InputStream getResourceAsInputStream() throws IOException { 069 // try to get the resource input stream 070 InputStream is; 071 if (isContentCache()) { 072 synchronized (this) { 073 if (buffer == null) { 074 log.debug("Reading resource: {} into the content cache", resourceUri); 075 is = getResourceAsInputStreamWithoutCache(); 076 buffer = IOConverter.toBytes(is); 077 IOHelper.close(is, resourceUri, log); 078 } 079 } 080 log.debug("Using resource: {} from the content cache", resourceUri); 081 return new ByteArrayInputStream(buffer); 082 } 083 084 return getResourceAsInputStreamWithoutCache(); 085 } 086 087 protected InputStream getResourceAsInputStreamWithoutCache() throws IOException { 088 return loadResource(resourceUri); 089 } 090 091 /** 092 * Loads the given resource. 093 * 094 * @param uri uri of the resource. 095 * @return the loaded resource 096 * @throws IOException is thrown if resource is not found or cannot be loaded 097 */ 098 protected InputStream loadResource(String uri) throws IOException { 099 return ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), uri); 100 } 101 102 @ManagedAttribute(description = "Whether the resource is cached") 103 public boolean isContentCache() { 104 return contentCache; 105 } 106 107 @ManagedOperation(description = "Clears the cached resource, forcing to re-load the resource on next request") 108 public void clearContentCache() { 109 log.debug("Clearing resource: {} from the content cache", resourceUri); 110 buffer = null; 111 } 112 113 public boolean isContentCacheCleared() { 114 return buffer == null; 115 } 116 117 @ManagedAttribute(description = "Camel context ID") 118 public String getCamelId() { 119 return getCamelContext().getName(); 120 } 121 122 @ManagedAttribute(description = "Camel ManagementName") 123 public String getCamelManagementName() { 124 return getCamelContext().getManagementName(); 125 } 126 127 @ManagedAttribute(description = "Endpoint service state") 128 public String getState() { 129 return getStatus().name(); 130 } 131 132 /** 133 * Sets whether to use resource content cache or not. 134 */ 135 public void setContentCache(boolean contentCache) { 136 this.contentCache = contentCache; 137 } 138 139 public String getResourceUri() { 140 return resourceUri; 141 } 142 143 /** 144 * Path to the resource, or a reference to lookup a bean in the Registry to use as the resource 145 * 146 * @param resourceUri the resource path 147 */ 148 public void setResourceUri(String resourceUri) { 149 this.resourceUri = resourceUri; 150 } 151}