📄 providedserviceconfig.java
字号:
/** * Copyright 2004 The Apache Software Foundation * * 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.apache.lucene.gdata.server.registry;import java.lang.reflect.Constructor;import javax.xml.transform.Templates;import javax.xml.transform.TransformerConfigurationException;import javax.xml.transform.TransformerFactory;import javax.xml.transform.stream.StreamSource;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.lucene.gdata.search.config.IndexSchema;import org.apache.lucene.gdata.utils.Pool;import org.apache.lucene.gdata.utils.PoolObjectFactory;import org.apache.lucene.gdata.utils.SimpleObjectPool;import com.google.gdata.data.BaseEntry;import com.google.gdata.data.BaseFeed;import com.google.gdata.data.ExtensionProfile;/** * Standard implementation of * {@link org.apache.lucene.gdata.server.registry.ProvidedService} to be used * inside the * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} * <p> * ExtensionProfiles are used to generate and parse xml by the gdata api. For * that case all methods are synchronized. This will slow down the application * when performing lots of xml generation concurrently. For that case the * extensionProfile for a specific service will be pooled and reused. * </p> * * * @author Simon Willnauer * */@Scope(scope = Scope.ScopeType.REQUEST)public class ProvidedServiceConfig implements ProvidedService, ScopeVisitor { private final static Log LOG = LogFactory .getLog(ProvidedServiceConfig.class); private static final int DEFAULT_POOL_SIZE = 5; private IndexSchema indexSchema; /* * To ensure a extension profile instance will not be shared within multiple * threads each thread requesting a config will have one instance for the * entire request. */ protected final ThreadLocal<ExtensionProfile> extProfThreadLocal = new ThreadLocal<ExtensionProfile>(); /* * ExtensionProfiles are used to generate and parse xml by the gdata api. * For that case all methodes are synchronized. This will slow down the * application when performing lots of xml generation concurrently. for that * case the extensionProfile for a specific service will be pooled and * reused. */ private Pool<ExtensionProfile> profilPool; private String serviceName; private Class<? extends BaseEntry> entryType; private Class<? extends BaseFeed> feedType; private ExtensionProfile extensionProfile; private int poolSize = DEFAULT_POOL_SIZE; private Templates transformerTemplate; /** * @return Returns the poolSize. */ public int getPoolSize() { return this.poolSize; } /** * @param poolSize * The poolSize to set. */ public void setPoolSize(int poolSize) { this.poolSize = poolSize >= DEFAULT_POOL_SIZE ? poolSize : DEFAULT_POOL_SIZE; } /** * Default constructor to instantiate via reflection */ public ProvidedServiceConfig() { try { GDataServerRegistry.getRegistry().registerScopeVisitor(this); } catch (RegistryException e) { throw new RuntimeException("Can not register ScopeVisitor -- " + e.getMessage(), e); } } /** * @see org.apache.lucene.gdata.server.registry.ProvidedService#getFeedType() */ public Class getFeedType() { return this.feedType; } /** * @param feedType * The feedType to set. */ public void setFeedType(Class feedType) { this.feedType = feedType; } /** * @see org.apache.lucene.gdata.server.registry.ProvidedService#getExtensionProfile() */ public ExtensionProfile getExtensionProfile() { ExtensionProfile ext = this.extProfThreadLocal.get(); if (ext != null) { return ext; } if(this.extensionProfile == null) return null; if (this.profilPool == null) createProfilePool(); ext = this.profilPool.aquire(); this.extProfThreadLocal.set(ext); return ext; } /** * @param extensionProfil - * the extension profile for this feed configuration */ @SuppressWarnings("unchecked") public void setExtensionProfile(ExtensionProfile extensionProfil) { if (extensionProfil == null) throw new IllegalArgumentException( "ExtensionProfile must not be null"); if (this.extensionProfile != null) return; this.extensionProfile = extensionProfil; } private void createProfilePool() { if (LOG.isInfoEnabled()) LOG.info("Create ExtensionProfile pool with pool size:" + this.poolSize + " for service " + this.serviceName); this.profilPool = new SimpleObjectPool<ExtensionProfile>(this.poolSize, new ExtensionProfileFactory<ExtensionProfile>( this.extensionProfile.getClass(),this.entryType,this.feedType)); } /** * TODO add comment * * @param <E> * @param extensionProfileClass * @throws InstantiationException * @throws IllegalAccessException */ public <E extends ExtensionProfile> void setExtensionProfileClass( Class<E> extensionProfileClass) throws InstantiationException, IllegalAccessException { if (extensionProfileClass == null) throw new IllegalArgumentException( "ExtensionProfile class must not be null"); setExtensionProfile(extensionProfileClass.newInstance()); } /** * @see org.apache.lucene.gdata.server.registry.ProvidedService#getEntryType() */ public Class getEntryType() { return this.entryType; } /** * @param entryType */ public void setEntryType(Class entryType) { this.entryType = entryType; } /** * @see org.apache.lucene.gdata.server.registry.ProvidedService#getName() */ public String getName() { return this.serviceName; } /** * @param serviceName */ public void setName(String serviceName) { this.serviceName = serviceName; } /** * @see org.apache.lucene.gdata.server.registry.ProvidedService#destroy() */ public void destroy() { if (this.profilPool != null) this.profilPool.destroy(); if (LOG.isInfoEnabled()) LOG.info("Destroy Service " + this.serviceName + " -- release all resources"); this.feedType = null; this.entryType = null; this.extensionProfile = null; } private static class ExtensionProfileFactory<Type extends ExtensionProfile> implements PoolObjectFactory<Type> { private final Class<? extends ExtensionProfile> clazz; private final Constructor<? extends ExtensionProfile> constructor; private static final Object[] constArray = new Object[0]; private BaseEntry entry; private BaseFeed feed; ExtensionProfileFactory(Class<? extends ExtensionProfile> clazz, Class<? extends BaseEntry> entryClass, Class<? extends BaseFeed> feedClass) { this.clazz = clazz; try { this.constructor = clazz.getConstructor(new Class[0]); this.entry = entryClass.newInstance(); this.feed = feedClass.newInstance(); } catch (Exception e) { throw new IllegalArgumentException( "The given class has no default constructor -- can not use as a ExtensionProfile -- " + this.clazz.getName(), e); } } /** * @see org.apache.lucene.gdata.utils.PoolObjectFactory#getInstance() */ @SuppressWarnings("unchecked") public Type getInstance() { try { Type retValue = (Type) this.constructor.newInstance(constArray); this.entry.declareExtensions(retValue); this.feed.declareExtensions(retValue); return retValue; } catch (Exception e) { throw new RuntimeException( "Can not instantiate new ExtensionProfile -- ", e); } } /** * @param type - * the ExtensionProfile to destroy * @see org.apache.lucene.gdata.utils.PoolObjectFactory#destroyInstance(Object) */ public void destroyInstance(Type type) { // } } /** * @see org.apache.lucene.gdata.server.registry.ScopeVisitor#visiteInitialize() */ public void visiteInitialize() { if(this.profilPool == null) createProfilePool(); /* * don't set a extension profile for each thread. The current thread * might use another service and does not need the extension profile of * this service */ } /** * @see org.apache.lucene.gdata.server.registry.ScopeVisitor#visiteDestroy() */ public void visiteDestroy() { /* * Check every thread after request destroyed to release all profiles to * the pool */ ExtensionProfile ext = this.extProfThreadLocal.get(); if (ext == null) { if(LOG.isDebugEnabled()) LOG.debug("ThreadLocal owns no ExtensionProfile in requestDestroy for service " + this.serviceName); return; } this.extProfThreadLocal.set(null); this.profilPool.release(ext); } /** * @return Returns the indexSchema. */ public IndexSchema getIndexSchema() { return this.indexSchema; } /** * @param indexSchema The indexSchema to set. */ public void setIndexSchema(IndexSchema indexSchema) { this.indexSchema = indexSchema; if(this.indexSchema != null) this.indexSchema.setName(this.serviceName); } /** * @see org.apache.lucene.gdata.server.registry.ProvidedService#getTransformTemplate() */ public Templates getTransformTemplate() { return this.transformerTemplate; } /** * Sets and creates the preview transformer xslt template to provide a html formate for feeds and entries. * The given file name must be available in the classpath. * @param filename - the name of the file in the classpath */ public void setXsltStylesheet(String filename){ if(filename == null || filename.length() == 0){ LOG.info("No preview stylesheet configured for service "+this.serviceName); return; } TransformerFactory factory = TransformerFactory.newInstance(); try { this.transformerTemplate = factory.newTemplates(new StreamSource(ProvidedServiceConfig.class.getResourceAsStream(filename.startsWith("/")?filename:"/"+filename))); } catch (TransformerConfigurationException e) { throw new RuntimeException("Can not compile xslt stylesheet path: "+filename,e); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -