View Javadoc

1   /*
2    * Copyright 2007-2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.gwe.p2elv2.model;
18  
19  import java.io.Serializable;
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.List;
23  import java.util.Set;
24  
25  import org.gwe.p2elv2.P2ELDependentVariableNotResolvedException;
26  import org.gwe.p2elv2.P2ELFunctionNotSupported;
27  import org.gwe.p2elv2.PFunction;
28  import org.gwe.p2elv2.PPermutation;
29  import org.gwe.p2elv2.PStatementContext;
30  import org.gwe.p2elv2.PVarValueSpace;
31  import org.gwe.p2elv2.functions.PFConst;
32  import org.gwe.utils.rex.config.REXConfig4Class;
33  import org.gwe.utils.rex.config.REXConfig4Field;
34  import org.gwe.utils.rex.config.REXConfig4ListElement;
35  import org.gwe.utils.rex.config.REXConfig4String;
36  
37  /**
38   * @author Marco Ruiz
39   * @since Jul 30, 2008
40   */
41  @REXConfig4Class(rexPieces={"\\s*\\${1,2}\\{\\s*", "nameParts", "\\}\\s*=", "functionInvocation|constantValue", "\\s*"})
42  public class PVariable implements Serializable {
43  	
44  	public static final String SYS_VAR_PREFIX = "SYSTEM";
45  	public static final String RUN_VAR_PREFIX = "RUNTIME";
46  	
47  	@REXConfig4ListElement(pattern=@REXConfig4Field(field="[_a-zA-Z]\\w*", suffix="[.]?"), min=1)
48  	private List<String> nameParts = null;
49  
50  	private PFunctionInvocation functionInvocation = null;
51  
52  	@REXConfig4String(pattern=@REXConfig4Field(field="[^\\s]*"))
53  	private String constantValue = null;
54  	
55  	protected String name = "";
56  	private String dimension = "";
57  	
58  	public PVariable() {}
59  	
60  	public PVariable(String name, String constantValue) {
61  		setNameParts(name);
62  		setConstantValue(constantValue);
63  	}
64  	
65  	public void setNameParts(String... nameParts) {
66  		setNameParts(new ArrayList<String>(Arrays.asList(nameParts)));
67  	}
68  	
69  	public void setNameParts(List<String> nameParts) {
70  		if (nameParts.isEmpty()) return;
71  		name = nameParts.remove(0);
72  		if (nameParts.isEmpty()) return;
73  		dimension = nameParts.remove(0);
74  		for (String part : nameParts) dimension += "." + part;
75      }
76  
77  	public String getName() {
78  		return name;
79      }
80  
81  	public String getDimension() {
82  		return dimension;
83      }
84  	
85  	public PFunctionInvocation getFunctionInvocation() {
86  		return functionInvocation; 
87  	}
88  	
89  	public void setFunctionInvocation(PFunctionInvocation functionInvocation) {
90  		this.functionInvocation = functionInvocation; 
91  	}
92  	
93  	public void setConstantValue(String constantValue) {
94  		this.constantValue = constantValue;
95  		// In "const" function form
96  		setFunctionInvocation(PFunctionInvocation.create(PFConst.FUNCTION_NAME, constantValue));
97      }
98  
99  	public boolean isSingleValue() throws P2ELFunctionNotSupported {
100 	    return getFunction().isSingleValue(functionInvocation.getParams());
101     }
102 
103 	public boolean isRuntime() throws P2ELFunctionNotSupported {
104 	    return getFunction().isRuntime();
105     }
106 
107 	private PFunction getFunction() throws P2ELFunctionNotSupported {
108 	    PFunction result = functionInvocation.getFunction();
109 	    if (result == null) throw new P2ELFunctionNotSupported(functionInvocation.getFunctionName());
110 	    return result;
111     }
112 
113 	public boolean isVarConstSingleValue() {
114 	    try {
115 	        return isSingleValue() && getFunctionInvocation().getFunction().getClass().equals(PFConst.class);
116         } catch (P2ELFunctionNotSupported e) {
117         	return false;
118         }
119     }
120 	
121 	public boolean isPermutable() {
122 	    try {
123 	        return !isSingleValue() && !isRuntime() && !isDependentOnSystemVars() &&  !isDependentOnRuntimeVars();
124         } catch (P2ELFunctionNotSupported e) {
125         	return false;
126         }
127     }
128 
129 	public PVarValueSpace generateValueSpace(PPermutation permKey, PStatementContext ctx) throws P2ELDependentVariableNotResolvedException, P2ELFunctionNotSupported {
130 	    try {
131 	    	List<String> evalParams = functionInvocation.evalParams(permKey.asVTLModel());
132 		    return getFunction().calculateValues(evalParams, ctx);
133 	    } catch (P2ELDependentVariableNotResolvedException e) {
134 	    	e.setVariable(this);
135 	    	throw e;
136 	    }
137     }
138 
139 	public String getFullName() {
140 	    return name + (dimension.equals("") ? "" : "." + dimension);
141     }
142 
143 	public String getVarReference() {
144 	    return "${" + getFullName() + "}";
145     }
146 
147 	public String toString() {
148 		String value = (constantValue != null) ? constantValue : functionInvocation.toString(); 
149 		return getVarReference() + "=" + value; 
150 	}
151 	
152 	//========================
153 	// DEPENDENCIES UTILITIES
154 	//========================
155 
156 	public boolean isVarResolvedBy(List<PVariable> varsResolved, String... varsResolvedGroups) {
157 	    Set<String> varDependencyNames = getVarDependencyNames();
158 	    for (String dep : varDependencyNames) 
159         	if (!isDependencyResolvedByGroups(dep, varsResolvedGroups) && !isDependencyResolvedByVars(dep, varsResolved))
160         		return false;
161 
162 	    return true;
163     }
164 	
165 	private boolean isDependencyResolvedByGroups(String dependency, String... varsResolvedGroups) {
166     	for (String group : varsResolvedGroups) 
167             if (dependency.startsWith(group)) return true;
168     	
169     	return false;
170 	}
171 	
172 	private boolean isDependencyResolvedByVars(String dependency, List<PVariable> varsResolved) {
173         for (PVariable var : varsResolved) 
174             if (var.getName().equals(dependency)) return true;
175     	
176     	return false;
177 	}
178 	
179 	public int getDependencyOrder(List<PVariable> varsSortedByDependencyLevel) {
180 	    Set<String> varDependencyNames = getVarDependencyNames();
181 	    int idx = varsSortedByDependencyLevel.size();
182 	    for (; idx > 0; idx--) {
183 			PVariable sortedVar = varsSortedByDependencyLevel.get(idx - 1);
184 			if (varDependencyNames.contains(sortedVar.getName())) 
185 	        	break;
186 	    }
187 	    return idx;
188     }
189 	
190 	public boolean isDependentOnSystemVars() {
191 		for (String varName : getVarDependencyNames()) 
192 	        if (varName.startsWith(SYS_VAR_PREFIX)) 
193 	        	return true;
194 		
195 		return false;
196 	}
197 	
198 	public boolean isDependentOnRuntimeVars() {
199 		for (String varName : getVarDependencyNames()) 
200 	        if (varName.startsWith(RUN_VAR_PREFIX)) 
201 	        	return true;
202 		
203 		return false;
204 	}
205 	
206 	public Set<String> getVarDependencyNames() {
207 	    return functionInvocation.getVarDependencyNames();
208     }
209 }
210