/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* 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 com.asakusafw.runtime.core.legacy;
import java.io.IOException;
import java.text.MessageFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.asakusafw.runtime.core.ResourceConfiguration;
/**
* Runtime resource which has resource lifecycle.
* @since 0.9.0
*/
public interface RuntimeResource {
/**
* Initializes this resource.
* @param configuration the current configuration
* @throws IOException if failed to initialize this resource
* @throws InterruptedException if interrupted while initializing this resource
* @throws IllegalArgumentException if configuration is not valid
* @throws IllegalStateException if resource lifecycle has something wrong
*/
default void setup(ResourceConfiguration configuration) throws IOException, InterruptedException {
return;
}
/**
* Finalizes this resource.
* @param configuration the current configuration
* @throws IOException if failed to finalizing this resource
* @throws InterruptedException if interrupted while finalizing this resource
* @throws IllegalArgumentException if configuration is not valid
* @throws IllegalStateException if resource lifecycle has something wrong
*/
default void cleanup(ResourceConfiguration configuration) throws IOException, InterruptedException {
return;
}
/**
* A skeletal implementation of registering/unregistering resource delegation objects.
* @param <D> the delegation object type
*/
abstract class DelegateRegisterer<D> implements RuntimeResource {
static final Log LOG = LogFactory.getLog(RuntimeResource.DelegateRegisterer.class);
private D registered;
/**
* Returns the configuration key of the delegation object class name.
* @return the delegation object class name
*/
protected abstract String getClassNameKey();
/**
* Returns the interface type of the delegation object.
* @return the delegation object interface type
*/
protected abstract Class<? extends D> getInterfaceType();
/**
* Registers the delegation object.
* @param delegate the delegation object
* @param configuration the current configuration
* @throws IOException if failed to register the object by I/O error
* @throws InterruptedException if interrupted while registering the object
*/
protected abstract void register(D delegate, ResourceConfiguration configuration)
throws IOException, InterruptedException;
/**
* Unregisters the delegation object.
* @param delegate the delegation object
* @param configuration the current configuration
* @throws IOException if failed to unregister the object by I/O error
* @throws InterruptedException if interrupted while unregistering the object
*/
protected abstract void unregister(D delegate, ResourceConfiguration configuration)
throws IOException, InterruptedException;
@Override
public void setup(ResourceConfiguration configuration) throws IOException,
InterruptedException {
String className = configuration.get(getClassNameKey(), null);
if (className == null) {
LOG.warn(MessageFormat.format(
"Missing \"{0}\" in plugin configurations (API:{1})",
getClassNameKey(),
getInterfaceType().getName()));
return;
}
if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format(
"Loading plugin for {0}: key={1}, value={2}", //$NON-NLS-1$
getInterfaceType().getName(),
getClassNameKey(),
className));
}
D loaded = loadDelegate(configuration, className);
if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format(
"Registering plugin {2} into {0}", //$NON-NLS-1$
getInterfaceType().getName(),
getClassNameKey(),
className));
}
register(loaded, configuration);
this.registered = loaded;
if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format(
"Registered plugin {2} into {0}", //$NON-NLS-1$
getInterfaceType().getName(),
getClassNameKey(),
className));
}
}
@Override
public void cleanup(ResourceConfiguration configuration)
throws IOException, InterruptedException {
if (registered != null) {
unregister(registered, configuration);
if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format(
"Unregistered plugin {1} from {0}", //$NON-NLS-1$
getInterfaceType().getName(),
registered.getClass().getName()));
}
registered = null;
}
}
private D loadDelegate(ResourceConfiguration configuration, String className) throws IOException {
assert configuration != null;
assert className != null;
try {
Class<?> aClass = configuration.getClassLoader().loadClass(className);
Class<? extends D> delegate = aClass.asSubclass(getInterfaceType());
D instance = delegate.newInstance();
return instance;
} catch (Exception e) {
throw new IOException(MessageFormat.format(
"Failed to initialize a plugin {0}",
className), e);
}
}
}
}