00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.xml;
00032
00033 import java.io.FileInputStream;
00034 import java.io.Serializable;
00035 import java.util.HashMap;
00036 import java.util.Iterator;
00037 import java.util.Properties;
00038 import java.util.regex.Matcher;
00039 import java.util.regex.Pattern;
00040
00041 import org.apache.log4j.Logger;
00042 import org.objectweb.proactive.core.descriptor.xml.VariablesHandler;
00043 import org.objectweb.proactive.core.util.log.Loggers;
00044 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00045 import org.xml.sax.SAXException;
00046
00047
00053 public class VariableContract implements Serializable {
00054 static Logger logger = ProActiveLogger.getLogger(Loggers.DEPLOYMENT);
00055 public static VariableContract xmlproperties = null;
00056 public static final Lock lock = new Lock();
00057 private boolean closed;
00058
00059 private static final Pattern variablePattern = Pattern.compile("(\\$\\{(.*?)\\})");
00060 private static final Pattern legalPattern = Pattern.compile("^\\$\\{[\\w\\.]+\\}$");
00061
00062 private class PropertiesDatas {
00063 public String value;
00064 public VariableContractType type;
00065 public String setFrom;
00066
00067 public String toString() {
00068 StringBuilder sb = new StringBuilder();
00069
00070 sb.append(value).append(" type=").append(type).append(" setFrom=")
00071 .append(setFrom);
00072 return sb.toString();
00073 }
00074 }
00075
00076 private HashMap list;
00077
00082 public VariableContract() {
00083 list = new HashMap();
00084 closed = false;
00085 }
00086
00090 public void close() {
00091 closed = true;
00092 }
00093
00099 public boolean isClosed() {
00100 return closed;
00101 }
00102
00115 public void setVariableFromProgram(String name, String value,
00116 VariableContractType type) {
00117 setVariableFrom(name, value, type, "Program");
00118 setFromJavaProperty(name, type);
00119 }
00120
00125 public void setJavaPropertiesValues(){
00126
00127 java.util.Iterator it = list.keySet().iterator();
00128 while (it.hasNext()) {
00129 String name = (String) it.next();
00130 PropertiesDatas data = (PropertiesDatas) list.get(name);
00131 setFromJavaProperty(name, data.type);
00132 }
00133 }
00134
00141 public void setFromJavaProperty(String name, VariableContractType type){
00142
00143 if(!type.hasSetAbility("JavaProperty")) return;
00144
00145 try {
00146 String value = System.getProperty(name);
00147 if(logger.isDebugEnabled()){
00148 logger.debug("Found java property "+name+"="+value);
00149 }
00150 if (value == null) value="";
00151 setVariableFrom(name, value, type, "JavaProperty");
00152 } catch (Exception ex) {
00153 if (logger.isDebugEnabled())
00154 logger.debug("Unable to get java property: " + name);
00155 }
00156 }
00157
00167 private void setVariableFrom(String name, String value,
00168 VariableContractType type, String from) {
00169 if (logger.isDebugEnabled()) {
00170 logger.debug("Setting from " + from + ": " + type + " " + name +
00171 "=" + value);
00172 }
00173
00174 if (closed) {
00175 throw new IllegalArgumentException(
00176 "Variable Contract is Closed. Variables can no longer be set");
00177 }
00178
00179 checkGenericLogic(name, value, type);
00180
00181 if ((value.length() > 0) && !type.hasSetAbility(from)) {
00182 throw new IllegalArgumentException("Variable " + name +
00183 " can not be set from " + from + " for type: " + type);
00184 }
00185
00186 if ((value.length() <= 0) && !type.hasSetEmptyAbility(from)) {
00187 throw new IllegalArgumentException("Variable " + name +
00188 " can not be set empty from " + from + " for type: " + type);
00189 }
00190
00191 if (list.containsKey(name)) {
00192 PropertiesDatas var = (PropertiesDatas) list.get(name);
00193
00194 if (!type.hasPriority(var.setFrom, from)) {
00195 if (logger.isDebugEnabled()) {
00196 logger.debug("Skipping, lower priority (" + from + " < " +
00197 var.setFrom + ") for type: " + type);
00198 }
00199 return;
00200 }
00201 }
00202
00203 unsafeAdd(name, value, type, from);
00204 }
00205
00212 public void setVariableFromProgram(HashMap map, VariableContractType type)
00213 throws NullPointerException {
00214 if ((map == null) || (type == null)) {
00215 throw new NullPointerException("Null arguments");
00216 }
00217
00218 String name;
00219 java.util.Iterator it = map.keySet().iterator();
00220 while (it.hasNext()) {
00221 name = (String) it.next();
00222 setVariableFromProgram(name, (String) map.get(name), type);
00223 }
00224 }
00225
00233 public void setDescriptorVariable(String name, String value,
00234 VariableContractType type) {
00235
00236 setVariableFrom(name, value, type, "Descriptor");
00237 setFromJavaProperty(name, type);
00238 }
00239
00245 public void load(String file) throws org.xml.sax.SAXException {
00246 Properties properties = new Properties();
00247 if (logger.isDebugEnabled()) {
00248 logger.debug("Loading propeties file:" + file);
00249 }
00250
00251
00252 try {
00253 FileInputStream stream = new FileInputStream(file);
00254 properties.load(stream);
00255 } catch (Exception ex) {
00256 if (logger.isDebugEnabled()) {
00257 logger.debug("Curret Working Directory: " +
00258 System.getProperty("user.dir"));
00259 }
00260
00261 throw new org.xml.sax.SAXException(
00262 "Tag property cannot open file : [" + file + "]");
00263 }
00264
00265 String name;
00266 String value;
00267 Iterator it = properties.keySet().iterator();
00268 while (it.hasNext()) {
00269 name = (String) it.next();
00270 value = properties.getProperty(name);
00271 setDescriptorVariable(name, value,
00272 VariableContractType.DescriptorVariable);
00273 }
00274 }
00275
00280 public void loadXML(String file) {
00281 if (logger.isDebugEnabled()) {
00282 logger.debug("Loading XML variable file:" + file);
00283 }
00284 VariablesHandler.createVariablesHandler(file, this);
00285 }
00286
00292 public String getValue(String name) {
00293 if (list.containsKey(name)) {
00294 PropertiesDatas var = (PropertiesDatas) list.get(name);
00295
00296 return var.value;
00297 }
00298
00299 return null;
00300 }
00301
00308 public String transform(String text) throws SAXException {
00309 if(text==null) return null;
00310
00311 Matcher m=variablePattern.matcher(text);
00312 StringBuffer sb=new StringBuffer();
00313 while(m.find()){
00314
00315 if(!isLegalName(m.group(1)))
00316 throw new SAXException("Error, malformed variable:"+m.group(1));
00317
00318 String name=m.group(2);
00319 String value=getValue(name);
00320
00321 if(value==null || value.length()<=0)
00322 throw new SAXException("Error, variable value not found: "+name+"=?");
00323
00324 if(logger.isDebugEnabled()){
00325 logger.debug("Matched:"+name+" = "+value);
00326
00327 }
00328 m.appendReplacement(sb, value);
00329 }
00330 m.appendTail(sb);
00331
00332 return sb.toString();
00333 }
00334
00341 private void checkGenericLogic(String name, String value,
00342 VariableContractType type) {
00343
00344
00345
00346
00347 if (name == null) {
00348 throw new NullPointerException("Variable Name is null.");
00349 }
00350
00351 if (name.length() <= 0) {
00352 throw new IllegalArgumentException("Variable Name is empty.");
00353 }
00354
00355 if (!isLegalName("${"+name+"}")) {
00356 throw new IllegalArgumentException("Illegal variable name:"+name);
00357 }
00358
00359
00360 if (value == null) {
00361 throw new NullPointerException("Variable Value is null.");
00362 }
00363
00364 if (type == null) {
00365 throw new NullPointerException("Variable Type is null.");
00366 }
00367
00368 if (list.containsKey(name) &&
00369 !((PropertiesDatas) list.get(name)).type.equals(type)) {
00370 throw new IllegalArgumentException("Variable " + name +
00371 " is already defined with type: " +
00372 ((PropertiesDatas) list.get(name)).type);
00373 }
00374
00375 }
00376
00385 private void unsafeAdd(String name, String value,
00386 VariableContractType type, String setFrom)
00387 throws NullPointerException, IllegalArgumentException {
00388 if (name == null) {
00389 throw new NullPointerException("XML Variable Name is null.");
00390 }
00391 if (name.length() <= 0) {
00392 throw new IllegalArgumentException("XML Variable Name is empty.");
00393 }
00394 if (value == null) {
00395 throw new NullPointerException("XML Variable Value is null.");
00396 }
00397
00398 PropertiesDatas data;
00399 if (list.containsKey(name)) {
00400 data = (PropertiesDatas) list.get(name);
00401 if (logger.isDebugEnabled()) {
00402 logger.debug("...Modifying variable registry: "+name+"="+value);
00403 }
00404 } else {
00405 data = new PropertiesDatas();
00406 if (logger.isDebugEnabled()) {
00407 logger.debug("...Creating new registry for variable: "+name+"="+value);
00408 }
00409 }
00410
00411 data.type = type;
00412 data.value = value;
00413 data.setFrom = setFrom;
00414 list.put(name, data);
00415 }
00416
00422 public boolean checkContract() {
00423 boolean retval = true;
00424 String name;
00425 java.util.Iterator it = list.keySet().iterator();
00426 while (it.hasNext()) {
00427 name = (String) it.next();
00428 PropertiesDatas data = (PropertiesDatas) list.get(name);
00429
00430 if(data.value.length()<=0){
00431 logger.error(data.type.getEmptyErrorMessage(name));
00432 retval=false;
00433 }
00434 }
00435
00436 return retval;
00437 }
00438
00439 public String toString() {
00440 StringBuilder sb = new StringBuilder();
00441
00442 PropertiesDatas var;
00443 String name;
00444 java.util.Iterator it = list.keySet().iterator();
00445 while (it.hasNext()) {
00446 name = (String) it.next();
00447 var = (PropertiesDatas) list.get(name);
00448
00449 sb.append(name).append("=").append(var).append("\n");
00450 }
00451
00452 return sb.toString();
00453 }
00454
00460 public boolean isLegalName(String var){
00461 Matcher m = legalPattern.matcher(var);
00462 return m.matches();
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00676 static public class Lock {
00677 private boolean locked;
00678
00679 private Lock() {
00680 locked = false;
00681 }
00682
00687 public synchronized void release() {
00688 locked = false;
00689 notify();
00690 }
00691
00695 public synchronized void aquire() {
00696 while (locked) {
00697 try {
00698 wait();
00699 } catch (InterruptedException e) {
00700 }
00701 }
00702
00703 locked = true;
00704 }
00705 }
00706 }