Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * OfficeFloor - http://www.officefloor.net
   * Copyright (C) 2005-2011 Daniel Sagenschneider
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package net.officefloor.plugin.section.clazz;
 
 import java.util.List;
 import java.util.Map;
 

Class net.officefloor.compile.spi.section.source.SectionSource.

The implementation has been segregated into smaller methods to allow overriding to re-use ClassSectionSource for other uses.

Author(s):
Daniel Sagenschneider
 
 public class ClassSectionSource extends AbstractSectionSource {

 
 
 	protected final SectionDesigner getDesigner() {
 		return this.;
 	}

 
	protected final SectionSourceContext getContext() {
		return this.;
	}

	private final Map<StringSectionTask_tasksByName = new HashMap<StringSectionTask>();

	public SectionTask getTaskByName(String taskName) {
		return this..get(taskName);
	}

	private final Map<StringSectionTask_tasksByTypeName = new HashMap<StringSectionTask>();

	public SectionTask getTaskByTypeName(String taskTypeName) {
		return this..get(taskTypeName);
	}

Allows being made aware of further net.officefloor.compile.spi.section.SectionTask instances within the section to be considered for linking flows.

This allows ClassSectionSource to be used in conjunction with other functionality - such as template rendering for dynamic HTTP web pages.

	public void registerTaskByTypeName(String taskTypeNameSectionTask task) {
		this..put(taskTypeNametask);
	}

net.officefloor.compile.spi.section.SectionObject instances by fully qualified type name.
	public SectionObject getOrCreateObject(String typeName) {
		SectionObject sectionObject = this..get(typeName);
		if (sectionObject == null) {
			// No yet added, so add section object
			sectionObject = this.getDesigner().addSectionObject(typeName,
					typeName);
			this..put(typeNamesectionObject);
		}
		return sectionObject;
	}

net.officefloor.compile.spi.section.SectionManagedObject instances by fully qualified type name.
		return this..get(typeName);
	}

Obtains the net.officefloor.compile.spi.section.SectionOutput.

Should the net.officefloor.compile.spi.section.SectionOutput not yet be added, it is added.

Parameters:
name Name of the net.officefloor.compile.spi.section.SectionOutput.
argumentType Type of the argument. May be null if no argument.
isEscalationOnly true if escalation only.
Returns:
net.officefloor.compile.spi.section.SectionObject.
	public SectionOutput getOrCreateOutput(String nameString argumentType,
			boolean isEscalationOnly) {
		SectionOutput sectionOutput = this..get(name);
		if (sectionOutput == null) {
			// Not yet added, so add section output
			sectionOutput = this.getDesigner().addSectionOutput(name,
					argumentTypeisEscalationOnly);
			this..put(namesectionOutput);
		}
		return sectionOutput;
	}

	private final Map<Class<?>, SubSection_subSectionsByType = new HashMap<Class<?>, SubSection>();

Obtains the net.officefloor.compile.spi.section.SubSection.

Should the net.officefloor.compile.spi.section.SubSection not already be created, it is created.

Parameters:
sectionInterfaceType Type that is annotated with SectionInterface.
sectionAnnotation SectionInterface annotation.
Returns:
net.officefloor.compile.spi.section.SubSection.
	public SubSection getOrCreateSubSection(Class<?> sectionInterfaceType,
			SectionInterface sectionAnnotation) {
		// Determine if sub section already created for type
		SubSection subSection = this.
				.get(sectionInterfaceType);
		if (subSection != null) {
			return subSection;
		}
		// Sub section not registered, so create and register
		String subSectionSourceClassName = sectionAnnotation.source().getName();
		String subSectionLocation = ("".equals(sectionAnnotation.location())) ? sectionAnnotation
				.locationClass().getName() : sectionAnnotation.location();
		subSection = this.getDesigner().addSubSection(
				sectionInterfaceType.getSimpleName(),
				subSectionSourceClassNamesubSectionLocation);
		PropertyList subSectionProperties = this.getContext()
		for (Property property : sectionAnnotation.properties()) {
			String name = property.name();
			String value = ("".equals(property.value())) ? property
					.valueClass().getName() : property.value();
			subSection.addProperty(namevalue);
			subSectionProperties.addProperty(name).setValue(value);
		}
		// Register the sub section
		this..put(sectionInterfaceTypesubSection);
		// Link outputs of sub section
		for (FlowLink flowLink : sectionAnnotation.outputs()) {
			// Obtain the sub section output
			String subSectionOuputName = flowLink.name();
			SubSectionOutput subSectionOuput = subSection
					.getSubSectionOutput(subSectionOuputName);
			// Obtain the section task for output
			String linkTaskName = flowLink.method();
			SectionTask linkTask = this.getTaskByTypeName(linkTaskName);
			if (linkTask != null) {
				// Link flow internally
				this.getDesigner().link(subSectionOuputlinkTask);
			}
		}
		// Load the section type
		SectionType subSectionType = this.getContext().loadSectionType(
				subSectionSourceClassNamesubSectionLocation,
				subSectionProperties);
		// Link objects of sub section
		for (SectionObjectType subSectionObjectType : subSectionType
			// Obtain the sub section output
			String objectName = subSectionObjectType.getSectionObjectName();
			SubSectionObject subSectionObject = subSection
					.getSubSectionObject(objectName);
			// Link to managed object or external object
			String objectTypeName = subSectionObjectType.getObjectType();
			SectionManagedObject sectionManagedObject = this
					.getManagedObject(objectTypeName);
			if (sectionManagedObject != null) {
				// Link to section managed object
				this.getDesigner().link(subSectionObjectsectionManagedObject);
else {
				// Link to external object
				SectionObject sectionObject = this
						.getOrCreateObject(objectTypeName);
				this.getDesigner().link(subSectionObjectsectionObject);
			}
		}
		// Return the sub section
		return subSection;
	}

Obtains the name of the class for the section.

Returns:
Class name for the backing class of the section.
	protected String getSectionClassName() {
		String sectionClassName = this.getContext().getSectionLocation();
		return sectionClassName;
	}

Creates the net.officefloor.compile.spi.section.SectionManagedObject for providing the section object.

Parameters:
objectName Name of the object within the section.
sectionClass Section object class.
Returns:
net.officefloor.compile.spi.section.SectionManagedObject.
			Class<?> sectionClass) {
		// Create the managed object source
		SectionManagedObjectSource managedObjectSource = this.getDesigner()
		managedObjectSource.addProperty(
				sectionClass.getName());
		// Create the managed object
		SectionManagedObject managedObject = managedObjectSource
		return managedObject;
	}

Extracts the net.officefloor.plugin.managedobject.clazz.DependencyMetaData instances for the section object.

Parameters:
objectName Name of the object within the section.
sectionClass Section object class.
Returns:
Extracted net.officefloor.plugin.managedobject.clazz.DependencyMetaData instances for the section object.
Throws:
java.lang.Exception If fails to extract the net.officefloor.plugin.managedobject.clazz.DependencyMetaData instances.
			String objectNameClass<?> sectionClassthrows Exception {
	}

	protected String getTaskName(TaskType<?, ?, ?> taskType) {
		return taskType.getTaskName();
	}

	protected void enrichTask(SectionTask taskTaskType<?, ?, ?> taskType,
			Method taskMethodClass<?> parameterType) {
		// Obtain the task name
		String taskName = task.getSectionTaskName();
		// Obtain the parameter type name
		String parameterTypeName = (parameterType == null ? null
parameterType.getName());
		// Add input for task
		SectionInput sectionInput = this.getDesigner().addSectionInput(
				taskNameparameterTypeName);
		this.getDesigner().link(sectionInputtask);
	}

Links the next net.officefloor.frame.api.execute.Task.

Parameters:
task net.officefloor.compile.spi.section.SectionTask.
taskType net.officefloor.compile.work.TaskType.
taskMethod java.lang.reflect.Method for the net.officefloor.compile.spi.section.SectionTask.
argumentType Argument type. May be null if no argument type.
nextTaskAnnotation NextTask annotation on the java.lang.reflect.Method.
	protected void linkNextTask(SectionTask taskTaskType<?, ?, ?> taskType,
			Method taskMethodClass<?> argumentType,
			NextTask nextTaskAnnotation) {
		// Obtain the next task name
		String nextTaskName = nextTaskAnnotation.value();
		// Obtain the argument type name for the task
		String argumentTypeName = (argumentType == null ? null : argumentType
		// Attempt to obtain next task internally
		SectionTask nextTask = this.getTaskByTypeName(nextTaskName);
		if (nextTask != null) {
			// Link task internally
			this.getDesigner().link(tasknextTask);
else {
			// Not internal task, so link externally
			SectionOutput sectionOutput = this.getOrCreateOutput(nextTaskName,
					argumentTypeNamefalse);
			this.getDesigner().link(tasksectionOutput);
		}
	}

Links the net.officefloor.compile.spi.section.TaskFlow.

Parameters:
task net.officefloor.compile.spi.section.SectionTask.
taskType net.officefloor.compile.work.TaskType.
flowInterfaceType Interface type specifying the flows.
flowMethod Method on the interface for the flow to be linked.
flowArgumentType net.officefloor.compile.spi.section.TaskFlow argument type. May be null if no argument.
	protected void linkTaskFlow(SectionTask taskTaskType<?, ?, ?> taskType,
			Class<?> flowInterfaceTypeMethod flowMethod,
			Class<?> flowArgumentType) {
		// Obtain the flow name
		String flowName = flowMethod.getName();
		// Obtain the task flow
		TaskFlow taskFlow = task.getTaskFlow(flowName);
		// Obtain the flow argument name
		String flowArgumentTypeName = (flowArgumentType == null ? null
flowArgumentType.getName());
		// Determine if section interface (or flow interface)
		SectionInterface sectionAnnotation = flowInterfaceType
		if (sectionAnnotation != null) {
			// Section interface so obtain the sub section
			SubSection subSection = this.getOrCreateSubSection(
					flowInterfaceTypesectionAnnotation);
			// Link flow to sub section input
			SubSectionInput subSectionInput = subSection
			this.getDesigner().link(taskFlowsubSectionInput,
else {
			// Flow interface so attempt to obtain the task internally
			SectionTask linkTask = this.getTaskByTypeName(flowName);
			if (linkTask != null) {
				// Link flow internally
				this.getDesigner().link(taskFlowlinkTask,
else {
				// Not internal task, so link externally
				SectionOutput sectionOutput = this.getOrCreateOutput(flowName,
						flowArgumentTypeNamefalse);
				this.getDesigner().link(taskFlowsectionOutput,
			}
		}
	}

Links the net.officefloor.frame.api.execute.Task escalation.

Parameters:
task net.officefloor.compile.spi.section.SectionTask.
taskType net.officefloor.compile.work.TaskType.
escalationType net.officefloor.compile.work.TaskEscalationType.
escalationHandler Potential net.officefloor.compile.spi.section.SectionTask that can handle escalation based on its parameter. May be null if no net.officefloor.compile.spi.section.SectionTask can handle the escalation.
	protected void linkTaskEscalation(SectionTask task,
			TaskType<?, ?, ?> taskTypeTaskEscalationType escalationType,
			SectionTask escalationHandler) {
		// Obtain the escalation type name
		String escalationTypeName = escalationType.getEscalationType()
		// Obtain the task escalation
		TaskFlow taskEscalation = task.getTaskEscalation(escalationTypeName);
		// Link to escalation handler (if available)
		if (escalationHandler != null) {
			// Handle escalation internally
			this.getDesigner().link(taskEscalationescalationHandler,
else {
			// Not internally handled, so link externally
			SectionOutput sectionOutput = this.getOrCreateOutput(
					escalationTypeNameescalationTypeNametrue);
			this.getDesigner().link(taskEscalationsectionOutput,
		}
	}

	protected void linkTaskObject(SectionTask taskTaskType<?, ?, ?> taskType,
			TaskObjectType<?> objectType) {
		// Obtain the object name and its type
		String objectName = objectType.getObjectName();
		String objectTypeName = objectType.getObjectType().getName();
		// Obtain the task object
		TaskObject taskObject = task.getTaskObject(objectName);
		// Attempt to link to managed object
		SectionManagedObject mo = this.getManagedObject(objectTypeName);
		if (mo != null) {
			// Link to managed object
			this.getDesigner().link(taskObjectmo);
else {
			// Link to external object (by type)
			SectionObject sectionObject = this
					.getOrCreateObject(objectTypeName);
			this.getDesigner().link(taskObjectsectionObject);
		}
	}
	/*
	 * =================== SectionSource ===========================
	 */
	protected void loadSpecification(SpecificationContext context) {
		// No properties as uses location for class
	}
	public void sourceSection(SectionDesigner designer,
			SectionSourceContext contextthrows Exception {
		// Ensure only use once
		if (this. != null) {
			throw new IllegalStateException("May only use "
this.getClass().getName() + " once per instance");
		}
		// Initiate state
		this. = designer;
		this. = context;
		// Obtain the class
		String sectionClassName = this.getSectionClassName();
		if ((sectionClassName == null)
				|| (sectionClassName.trim().length() == 0)) {
			designer.addIssue(
					"Must specify section class name within the location",
					nullnull);
			return// not able to load if no section class specified
		}
		Class<?> sectionClass = context.getClassLoader().loadClass(
				sectionClassName);
		final String CLASS_OBJECT_NAME = "OBJECT";
		// Add the managed object for the section class
				CLASS_OBJECT_NAMEsectionClass);
		// Obtain the dependency meta-data
		DependencyMetaData[] dependencyMetaData = this
						sectionClass);
		// Load the managed objects
		for (DependencyMetaData dependency : dependencyMetaData) {
			// Obtain dependency name and type
			String dependencyName = dependency.name;
			String dependencyTypeName = dependency.field.getType().getName();
			// Obtain the managed object dependency
			ManagedObjectDependency moDependency = managedObject
			// Determine if managed object
			ManagedObject moAnnotation = dependency.field
			if (moAnnotation != null) {
				// Add the managed object
						.addSectionManagedObjectSource(dependencyTypeName,
								moAnnotation.source().getName());
				for (Property property : moAnnotation.properties()) {
					String value = ("".equals(property.value()) ? property
							.valueClass().getName() : property.value());
					mos.addProperty(property.name(), value);
				}
						dependencyTypeName.);
				// Register the managed object
				this..put(dependencyTypeNamemo);
				// Link dependency to managed object
				designer.link(moDependencymo);
else {
				// Link to external object (by type)
				SectionObject sectionObject = this
						.getOrCreateObject(dependencyTypeName);
				designer.link(moDependencysectionObject);
			}
		}
		// Link the managed object dependencies
		for (DependencyMetaData dependency : dependencyMetaData) {
			// Obtain managed object name
			String moName = dependency.field.getType().getName();
			// Obtain the managed object annotation
			ManagedObject annotation = dependency.field
			if (annotation == null) {
				continue// not managed object dependency
			}
			// Obtain the managed object
			// Load the managed object type
			PropertyList moProperties = context.createPropertyList();
			for (Property property : annotation.properties()) {
				String value = ("".equals(property.value()) ? property
						.valueClass().getName() : property.value());
				moProperties.addProperty(property.name()).setValue(value);
			}
					annotation.source().getName(), moProperties);
			// Link the dependencies for the managed object
			for (ManagedObjectDependencyType<?> dependencyType : moType
				// Obtain the dependency type
				String dependencyTypeName = dependencyType.getDependencyType()
				// Obtain the managed object dependency
				ManagedObjectDependency moDependency = mo
				// First attempt to link internally
				SectionManagedObject dependencyMo = this
						.getManagedObject(dependencyTypeName);
				if (dependencyMo != null) {
					// Link to managed object
					designer.link(moDependencydependencyMo);
else {
					// Link to external object (by type)
					SectionObject sectionObject = this
							.getOrCreateObject(dependencyTypeName);
					designer.link(moDependencysectionObject);
				}
			}
		}
		// Load the work type for the class
		PropertyList workProperties = context.createPropertyList();
		workProperties.addProperty(
				sectionClassName);
		WorkType<?> workType = context.loadWorkType(
				SectionClassWorkSource.class.getName(), workProperties);
		// Add the work for the section class
		SectionWork work = designer.addSectionWork("WORK",
				sectionClassName);
		// Load tasks
		Map<StringSectionTasktasksByParameterType = new HashMap<StringSectionTask>();
		Map<StringIntegerparameterIndexes = new HashMap<StringInteger>();
		for (TaskType<?, ?, ?> taskType : workType.getTaskTypes()) {
			// Obtain the task name
			String taskTypeName = taskType.getTaskName();
			String taskName = this.getTaskName(taskType);
			// Obtain the method for the task
			SectionTaskFactory taskFactory = (SectionTaskFactorytaskType
			Method method = taskFactory.getMethod();
			// Add the task (both by name and type name for internal linking)
			SectionTask task = work.addSectionTask(taskNametaskTypeName);
			this..put(taskNametask);
			this.registerTaskByTypeName(taskTypeNametask);
			// Obtain the parameter for the task
			int objectIndex = 1; // 1 as Section Object first
			Class<?> parameterType = null;
			Class<?>[] parameters = method.getParameterTypes();
			Annotation[][] parametersAnnotations = method
			for (int i = 0; i < parameters.lengthi++) {
				Class<?> parameter = parameters[i];
				Annotation[] parameterAnnotations = parametersAnnotations[i];
				// Determine if flow or section interface (not object)
				if ((parameter.getAnnotation(FlowInterface.class) != null)
						|| (parameter.getAnnotation(SectionInterface.class) != null)) {
					continue// ignore flow and section interfaces
				}
				// Determine if the parameter
				boolean isParameter = false;
				for (Annotation annotation : parameterAnnotations) {
					if (Parameter.class.equals(annotation.annotationType())) {
						isParameter = true;
					}
				}
				// Register as parameter
				if (isParameter) {
					// Ensure only one parameter
					if (parameterType != null) {
								"Method "
taskName
" may only have one parameter annotated with "
					}
					// Specify the parameter type
					parameterType = parameter;
					// Register the task by its parameter type
					tasksByParameterType.put(parameterType.getName(), task);
					// Register the parameter index for the task
					parameterIndexes
							.put(taskTypeNamenew Integer(objectIndex));
				}
				// Increment object index for parameter
				objectIndex++;
			}
			// Enrich the task
			this.enrichTask(tasktaskTypemethodparameterType);
		}
		// Link tasks
		for (TaskType<?, ?, ?> taskType : workType.getTaskTypes()) {
			// Obtain the task name
			String taskName = taskType.getTaskName();
			// Obtain the task
			SectionTask task = this.getTaskByTypeName(taskName);
			// Obtain the task method
			SectionTaskFactory taskFactory = (SectionTaskFactorytaskType
			Method method = taskFactory.getMethod();
			// Link the next task
			NextTask nextTaskAnnotation = method.getAnnotation(NextTask.class);
			if (nextTaskAnnotation != null) {
				// Obtain the argument type for the task
				Class<?> returnType = method.getReturnType();
				Class<?> argumentType = ((returnType == null)
						|| (void.class.equals(returnType)) || (.
						.equals(returnType))) ? null : returnType;
				// Link next task
				this.linkNextTask(tasktaskTypemethodargumentType,
						nextTaskAnnotation);
			}
			// Obtain the flow meta-data for the task
			ParameterFactory[] parameterFactories = taskFactory
			for (ParameterFactory factory : parameterFactories) {
				// Ignore if not flow parameter factory
				if (!(factory instanceof FlowParameterFactory)) {
					continue// ignore as not flow parameter factory
				}
				FlowParameterFactory flowParameterFactory = (FlowParameterFactoryfactory;
				// Add the flow meta-data
				flowMetaDatas.addAll(Arrays.asList(flowParameterFactory
			}
			// Sort the flows by index
			Collections.sort(flowMetaDatas,
						public int compare(FlowMethodMetaData a,
							return a.getFlowIndex() - b.getFlowIndex();
						}
					});
			// Link flows for the task
			for (FlowMethodMetaData flowMetaData : flowMetaDatas) {
				// Obtain the flow interface type
				Class<?> flowInterfaceType = flowMetaData.getFlowType();
				// Obtain the flow method
				Method flowMethod = flowMetaData.getMethod();
				// Obtain the argument type for the flow
				Class<?> flowArgumentType = null;
				Class<?>[] flowParameters = flowMethod.getParameterTypes();
				if (flowParameters.length > 0) {
					// Argument is always the first (and only) parameter
					flowArgumentType = flowParameters[0];
				}
				// Link the task flow
				this.linkTaskFlow(tasktaskTypeflowInterfaceType,
						flowMethodflowArgumentType);
			}
			// Link escalations for the task
			for (TaskEscalationType escalationType : taskType
				// Obtain task handling escalation (if available)
				String escalationTypeName = escalationType.getEscalationType()
				SectionTask escalationHandler = tasksByParameterType
						.get(escalationTypeName);
				// Link escalation
				this.linkTaskEscalation(tasktaskTypeescalationType,
						escalationHandler);
			}
			// Obtain the object index for the parameter
			Integer parameterIndex = parameterIndexes.get(taskName);
			// Obtain the object types
			TaskObjectType<?>[] objectTypes = taskType.getObjectTypes();
			// First object is always the section object
			TaskObjectType<?> sectionObjectType = objectTypes[0];
			TaskObject objectSection = task.getTaskObject(sectionObjectType
			designer.link(objectSectionmanagedObject);
			// Link remaining objects for task (1 as after section object)
			for (int i = 1; i < objectTypes.lengthi++) {
				TaskObjectType<?> objectType = objectTypes[i];
				// Determine if object is a parameter
				if ((parameterIndex != null)
						&& (parameterIndex.intValue() == i)) {
					// Parameter so flag as parameter
					String objectName = objectType.getObjectName();
					TaskObject taskObject = task.getTaskObject(objectName);
					taskObject.flagAsParameter();
					continue// next object
				}
				// Link the task object
				this.linkTaskObject(tasktaskTypeobjectType);
			}
		}
	}
New to GrepCode? Check out our FAQ X