⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlflowbuilder.java

📁 spring的WEB开发插件,支持多状态WEB开发
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		else if (flowDef.isClassRef()) {
			flow = getFlowServiceLocator().getFlow(flowDef.classRef);
		}
		else if (flowDef.shouldCreate()) {
			flow = getFlowServiceLocator().createFlow(flowDef.clazz, flowDef.autowire);
		}
		else {
			flow = getFlowServiceLocator().createFlow(flowDef.autowire);
		}
		flow.setId(element.getAttribute(ID_ATTRIBUTE));
		flow.setProperties(parseProperties(element));
		// set the flow under construction
		setFlow(flow);
	}

	/**
	 * Parse the state definitions in the XML file and add them to the flow
	 * object we're constructing.
	 */
	protected void parseStateDefinitions() {
		Element root = doc.getDocumentElement();
		String startStateId = root.getAttribute(START_STATE_ATTRIBUTE);
		// get the flow under construction
		Flow flow = getFlow();
		NodeList nodeList = root.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			if (node instanceof Element) {
				Element element = (Element)node;
				if (ACTION_STATE_ELEMENT.equals(element.getNodeName())) {
					parseAndAddActionState(flow, element);
				}
				else if (VIEW_STATE_ELEMENT.equals(element.getNodeName())) {
					parseAndAddViewState(flow, element);
				}
				else if (DECISION_STATE_ELEMENT.equals(element.getNodeName())) {
					parseAndAddDecisionState(flow, element);
				}
				else if (SUBFLOW_STATE_ELEMENT.equals(element.getNodeName())) {
					parseAndAddSubFlowState(flow, element);
				}
				else if (END_STATE_ELEMENT.equals(element.getNodeName())) {
					parseAndAddEndState(flow, element);
				}
			}
		}
		flow.setStartState(startStateId);
	}
	
	/**
	 * Parse a state definition from given element, returning given fallback state
	 * in case no other state object is identified.
	 */
	protected State parseStateDefinition(Element element, Class requiredStateType, State fallbackInstance) {
		FlowArtifact stateDef = parseFlowArtifactDefinition(element);
		State state;
		if (stateDef.isBeanRef()) {
			state = getFlowServiceLocator().getState(stateDef.bean);
		}
		else if (stateDef.isClassRef()) {
			state = getFlowServiceLocator().getState(stateDef.classRef);
		}
		else if (stateDef.shouldCreate()) {
			state = getFlowServiceLocator().createState(stateDef.clazz, stateDef.autowire);
		}
		else {
			state = fallbackInstance;
		}
		Assert.isInstanceOf(requiredStateType, state,
				"The state object for the '" + element.getAttribute(ID_ATTRIBUTE)
				+ "' state definition should subclass '" + ClassUtils.getShortName(requiredStateType) + "'");
		// parse any state entry actions
		List entryElements = DomUtils.getChildElementsByTagName(element, ENTRY_ELEMENT);
		if (!entryElements.isEmpty()) {
			Element entryElement = (Element)entryElements.get(0);
			state.setEntryAction(new CompositeAction(parseAnnotatedActions(entryElement)));
		}
		if (state instanceof TransitionableState) {
			// parse any state exit actions
			List exitElements = DomUtils.getChildElementsByTagName(element, EXIT_ELEMENT);
			if (!exitElements.isEmpty()) {
				Element exitElement = (Element)exitElements.get(0);
				((TransitionableState)state).setExitAction(new CompositeAction(parseAnnotatedActions(exitElement)));
			}		
			return state;
		}
		return state;
	}

	/**
	 * Parse given action state definition and add a corresponding state to
	 * given flow.
	 */
	protected void parseAndAddActionState(Flow flow, Element element) {
		ActionState actionState = (ActionState)parseStateDefinition(element, ActionState.class, new ActionState());
		actionState.setId(element.getAttribute(ID_ATTRIBUTE));
		actionState.setFlow(flow);
		actionState.addActions(parseAnnotatedActions(element));
		actionState.addAll(parseTransitions(element));
		actionState.setProperties(parseProperties(element));
	}

	/**
	 * Parse given view state definition and add a corresponding state to given
	 * flow.
	 */
	protected void parseAndAddViewState(Flow flow, Element element) {
		ViewState viewState = (ViewState)parseStateDefinition(element, ViewState.class, new ViewState());
		viewState.setId(element.getAttribute(ID_ATTRIBUTE));
		viewState.setFlow(flow);
		if (element.hasAttribute(VIEW_ATTRIBUTE)) {
			ViewDescriptorCreator creator = (ViewDescriptorCreator)
				fromStringTo(ViewDescriptorCreator.class).execute(element.getAttribute(VIEW_ATTRIBUTE));
			viewState.setViewDescriptorCreator(creator);
		}
		viewState.addAll(parseTransitions(element));
		viewState.setProperties(parseProperties(element));
	}

	/**
	 * Parse given decision state definition and add a corresponding state to given
	 * flow.
	 */
	protected void parseAndAddDecisionState(Flow flow, Element element) {
		DecisionState decisionState = (DecisionState)parseStateDefinition(element, DecisionState.class, new DecisionState());
		decisionState.setId(element.getAttribute(ID_ATTRIBUTE));
		decisionState.setFlow(flow);
		decisionState.addAll(parseIfs(element));
		decisionState.setProperties(parseProperties(element));
	}

	/**
	 * Parse given sub flow state definition and add a corresponding state to
	 * given flow.
	 */
	protected void parseAndAddSubFlowState(Flow flow, Element element) {
		SubflowState subflowState = (SubflowState)parseStateDefinition(element, SubflowState.class, new SubflowState());
		subflowState.setId(element.getAttribute(ID_ATTRIBUTE));
		subflowState.setFlow(flow);
		subflowState.setSubflow(getFlowServiceLocator().getFlow(element.getAttribute(FLOW_ATTRIBUTE)));
		subflowState.setAttributeMapper(parseAttributeMapper(element));
		subflowState.addAll(parseTransitions(element));
		subflowState.setProperties(parseProperties(element));
	}

	/**
	 * Parse given end state definition and add a corresponding state to given
	 * flow.
	 */
	protected void parseAndAddEndState(Flow flow, Element element) {
		EndState endState = (EndState)parseStateDefinition(element, EndState.class, new EndState());
		endState.setId(element.getAttribute(ID_ATTRIBUTE));
		endState.setFlow(flow);
		if (element.hasAttribute(VIEW_ATTRIBUTE)) {
			ViewDescriptorCreator creator = (ViewDescriptorCreator)
				fromStringTo(ViewDescriptorCreator.class).execute(element.getAttribute(VIEW_ATTRIBUTE));
			endState.setViewDescriptorCreator(creator);
		}
		endState.setProperties(parseProperties(element));
	}

	/**
	 * Parse all annotated action definitions contained in given element.
	 */
	protected AnnotatedAction[] parseAnnotatedActions(Element element) {
		List actions = new LinkedList();
		List actionElements = DomUtils.getChildElementsByTagName(element, ACTION_ELEMENT);
		Iterator it = actionElements.iterator();
		while (it.hasNext()) {
			actions.add(parseAnnotatedAction((Element)it.next()));
		}
		return (AnnotatedAction[])actions.toArray(new AnnotatedAction[actions.size()]);
	}

	/**
	 * Parse an annotated action definition and return the corresponding object.
	 */
	protected AnnotatedAction parseAnnotatedAction(Element element) {
		AnnotatedAction action = new AnnotatedAction((Action)parseAction(element));
		if (element.hasAttribute(NAME_ATTRIBUTE)) {
			action.setName(element.getAttribute(NAME_ATTRIBUTE));
		}
		if (element.hasAttribute(METHOD_ATTRIBUTE)) {
			// direct support for multi-actions
			action.setProperty(MultiAction.DefaultActionExecuteMethodNameResolver.METHOD_PROPERTY,
					element.getAttribute(METHOD_ATTRIBUTE));
		}
		parseAndAddProperties(element, action);
		return action;
	}

	/**
	 * Parse an action definition and return the corresponding object.
	 */
	protected Action parseAction(Element element) throws FlowBuilderException {
		FlowArtifact actionDef = parseFlowArtifactDefinition(element);
		if (actionDef.isBeanRef()) {
			return getFlowServiceLocator().getAction(actionDef.bean);
		}
		else if (actionDef.isClassRef()) {
			return getFlowServiceLocator().getAction(actionDef.classRef);
		}
		else if (actionDef.shouldCreate()) {
			return getFlowServiceLocator().createAction(actionDef.clazz, actionDef.autowire);
		}
		throw new FlowBuilderException(this, "Illegal action definition: '" + element + "'");
	}
	
	/**
	 * Parse all properties defined as nested elements of given element.
	 * Returns the properties as a map: the name of the property is the key, the 
	 * associated value the value.
	 */
	protected Map parseProperties(Element element) {
		MapAttributeSource properties = new MapAttributeSource();
		parseAndAddProperties(element, properties);
		return properties.getAttributeMap();
	}

	/**
	 * Parse all properties defined as nested elements of given element
	 * and add them to given set of properties.
	 */
	protected void parseAndAddProperties(Element element, MutableAttributeSource properties) {
		List propertyElements = DomUtils.getChildElementsByTagName(element, PROPERTY_ELEMENT);
		for (int i = 0; i < propertyElements.size(); i++) {
			parseAndAddProperty((Element)propertyElements.get(i), properties);
		}
	}

	/**
	 * Parse a property definition from given element and add the property
	 * to given set.
	 */
	protected void parseAndAddProperty(Element element, MutableAttributeSource properties) {
		String name = element.getAttribute(NAME_ATTRIBUTE);
		String value = null;
		if (element.hasAttribute(VALUE_ATTRIBUTE)) {
			value = element.getAttribute(VALUE_ATTRIBUTE);
		}
		else {
			List valueElements = DomUtils.getChildElementsByTagName(element, VALUE_ELEMENT);
			Assert.state(valueElements.size() == 1, "A property value should be specified for property '" + name + "'");
			value = DomUtils.getTextValue((Element)valueElements.get(0));
		}
		properties.setAttribute(name, convertPropertyValue(element, value));
	}
	
	/**
	 * Do type conversion for given property value.
	 */
	protected Object convertPropertyValue(Element element, String stringValue) {
		if (element.hasAttribute(TYPE_ATTRIBUTE)) {
			ConversionExecutor executor = fromStringToAliased(element.getAttribute(TYPE_ATTRIBUTE));
			if (executor != null) {
				// convert string value to instance of aliased type
				return executor.execute(stringValue);
			}
			else {
				Class targetClass = (Class)fromStringTo(Class.class).execute(element.getAttribute(TYPE_ATTRIBUTE));
				// convert string value to instance of target class
				return fromStringTo(targetClass).execute(stringValue);
			}
		}
		else {
			return stringValue;
		}
	}

	/**
	 * Find all transition definitions in given state definition and return a
	 * list of corresponding Transition objects.
	 */
	protected Transition[] parseTransitions(Element element) {
		List transitions = new LinkedList();
		List transitionElements = DomUtils.getChildElementsByTagName(element, TRANSITION_ELEMENT);
		for (int i = 0; i < transitionElements.size(); i++) {
			transitions.add(parseTransition((Element)transitionElements.get(i)));
		}
		return (Transition[])transitions.toArray(new Transition[transitions.size()]);
	}
	
	/**
	 * Parse a transition definition and return a corresponding Transition
	 * object.
	 */
	protected Transition parseTransition(Element element) {
		FlowArtifact transitionDef = parseFlowArtifactDefinition(element);
		Transition transition;
		if (transitionDef.isBeanRef()) {
			transition = getFlowServiceLocator().getTransition(transitionDef.bean);
		}
		else if (transitionDef.isClassRef()) {
			transition = getFlowServiceLocator().getTransition(transitionDef.classRef);
		}
		else if (transitionDef.shouldCreate()) {
			transition = getFlowServiceLocator().createTransition(transitionDef.clazz, transitionDef.autowire);
		}
		else {
			transition = new Transition();
		}
		TransitionCriteria matchingCriteria = (TransitionCriteria)
			fromStringTo(TransitionCriteria.class).execute(element.getAttribute(ON_ATTRIBUTE));
		transition.setMatchingCriteria(matchingCriteria);
		transition.setTargetStateId(element.getAttribute(TO_ATTRIBUTE));
		transition.setExecutionCriteria(TransitionCriteriaChain.criteriaChainFor(parseAnnotatedActions(element)));
		transition.setProperties(parseProperties(element));
		return transition;
	}

	/**
	 * Find all "if" definitions in given state definition and return a
	 * list of corresponding Transition objects.
	 */
	protected Transition[] parseIfs(Element element) {
		List transitions = new LinkedList();
		List transitionElements = DomUtils.getChildElementsByTagName(element, IF_ELEMENT);
		Iterator it = transitionElements.iterator();
		while (it.hasNext()) {
			transitions.addAll(Arrays.asList(parseIf((Element)it.next())));
		}
		return (Transition[])transitions.toArray(new Transition[transitions.size()]);
	}

	/**
	 * Parse an "if" transition definition and return a corresponding Transition
	 * object.
	 */
	protected Transition[] parseIf(Element element) {
		TransitionCriteria criteria = (TransitionCriteria)
			fromStringTo(TransitionCriteria.class).execute(element.getAttribute(TEST_ATTRIBUTE));
		String trueStateId = element.getAttribute(THEN_ATTRIBUTE);
		Transition thenTransition = new Transition(criteria, trueStateId);
		String falseStateId = element.getAttribute(ELSE_ATTRIBUTE);
		if (StringUtils.hasText(falseStateId)) {
			Transition elseTransition = new Transition(TransitionCriteriaFactory.alwaysTrue(), falseStateId);
			return new Transition[] { thenTransition, elseTransition };
		}
		else {
			return new Transition[] { thenTransition };
		}
	}

	/**
	 * Obtain an attribute mapper reference from given sub flow definition
	 * element and return the identified mapper, or null if no mapper is referenced.
	 */
	protected FlowAttributeMapper parseAttributeMapper(Element element) {
		List attributeMapperElements = DomUtils.getChildElementsByTagName(element, ATTRIBUTE_MAPPER_ELEMENT);
		if (attributeMapperElements.isEmpty()) {
			return null;
		}
		else {
			Element attributeMapperElement = (Element)attributeMapperElements.get(0);
			FlowArtifact mapperDef = parseFlowArtifactDefinition(attributeMapperElement);
			if (mapperDef.isBeanRef()) {
				return getFlowServiceLocator().getFlowAttributeMapper(mapperDef.bean);
			}
			else if (mapperDef.isClassRef()) {
				return getFlowServiceLocator().getFlowAttributeMapper(mapperDef.classRef);
			}
			else if (mapperDef.shouldCreate()) {
				return getFlowServiceLocator().createFlowAttributeMapper(mapperDef.clazz, mapperDef.autowire);
			}
			else {
				// inline definition of a mapping
				ParameterizableFlowAttributeMapper attributeMapper = new ParameterizableFlowAttributeMapper();
				List inputElements = DomUtils.getChildElementsByTagName(attributeMapperElement, INPUT_ELEMENT);
				List inputMappings = new ArrayList(inputElements.size());
				for (Iterator it = inputElements.iterator(); it.hasNext(); ) {
					parseAndAddMapping((Element)it.next(), inputMappings);
				}
				attributeMapper.setInputMappings(inputMappings);
				List outputElements = DomUtils.getChildElementsByTagName(attributeMapperElement, OUTPUT_ELEMENT);
				List outputMappings = new ArrayList(outputElements.size());
				for (Iterator it = outputElements.iterator(); it.hasNext(); ) {
					parseAndAddMapping((Element)it.next(), outputMappings);
				}
				attributeMapper.setOutputMappings(outputMappings);
				return attributeMapper;
			}
		}
	}

	/**
	 * Parse a single inline attribute mapping definition and add it to given map.
	 */
	protected void parseAndAddMapping(Element element, List mappings) {
		String name = element.getAttribute(NAME_ATTRIBUTE);
		String value = element.getAttribute(VALUE_ATTRIBUTE);
		String as = element.getAttribute(AS_ATTRIBUTE);
		String from = element.getAttribute(FROM_ATTRIBUTE);
		String to = element.getAttribute(TO_ATTRIBUTE);
		ConversionExecutor valueConverter = null;
		if (StringUtils.hasText(from)) {
			if (StringUtils.hasText(to)) {
				valueConverter = getConversionService().
					getConversionExecutor(getConversionService().getClassByAlias(from), getConversionService().getClassByAlias(to));
			}
		}
		if (StringUtils.hasText(name)) {
			// "name" allows you to specify the name of an attribute to map
			if (StringUtils.hasText(as)) {
				mappings.add(new Mapping(new FlowScopeExpression(name), ExpressionFactory.parsePropertyExpression(as), valueConverter));
			}
			else {
				mappings.add(new Mapping(new FlowScopeExpression(name), ExpressionFactory.parsePropertyExpression(name), valueConverter));
			}
		}
		else if (StringUtils.hasText(value)) {
			// "value" allows you to specify the value that should get mapped using an expression
			Assert.hasText(as, "The 'as' attribute is required with the 'value' attribute");
			mappings.add(new Mapping(ExpressionFactory.parseExpression(value), ExpressionFactory.parsePropertyExpression(as), valueConverter));
		}
		else {
			throw new FlowBuilderException(this, "Name or value is required in a mapping definition: " + element);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -