Coverage Report - org.jbehave.core.reporters.TemplateableOutput
 
Classes in this File Line Coverage Branch Coverage Complexity
TemplateableOutput
84%
76/90
43%
7/16
1.363
TemplateableOutput$OutputKeywords
62%
18/29
N/A
1.363
TemplateableOutput$OutputMeta
100%
7/7
100%
2/2
1.363
TemplateableOutput$OutputNarrative
100%
6/6
N/A
1.363
TemplateableOutput$OutputParameter
100%
7/7
N/A
1.363
TemplateableOutput$OutputRestart
100%
2/2
N/A
1.363
TemplateableOutput$OutputScenario
91%
22/24
83%
5/6
1.363
TemplateableOutput$OutputStep
78%
45/57
66%
16/24
1.363
TemplateableOutput$OutputStep$StepFormattingFailed
0%
0/2
N/A
1.363
TemplateableOutput$OutputStory
90%
10/11
N/A
1.363
 
 1  
 package org.jbehave.core.reporters;
 2  
 
 3  
 import java.io.File;
 4  
 import java.io.FileWriter;
 5  
 import java.io.Writer;
 6  
 import java.text.MessageFormat;
 7  
 import java.util.ArrayList;
 8  
 import java.util.HashMap;
 9  
 import java.util.List;
 10  
 import java.util.Map;
 11  
 import java.util.regex.Matcher;
 12  
 import java.util.regex.Pattern;
 13  
 
 14  
 import org.apache.commons.lang.StringEscapeUtils;
 15  
 import org.apache.commons.lang.StringUtils;
 16  
 import org.jbehave.core.configuration.Keywords;
 17  
 import org.jbehave.core.model.ExamplesTable;
 18  
 import org.jbehave.core.model.GivenStories;
 19  
 import org.jbehave.core.model.Meta;
 20  
 import org.jbehave.core.model.Narrative;
 21  
 import org.jbehave.core.model.OutcomesTable;
 22  
 import org.jbehave.core.model.Scenario;
 23  
 import org.jbehave.core.model.Story;
 24  
 import org.jbehave.core.model.StoryDuration;
 25  
 
 26  
 import freemarker.ext.beans.BeansWrapper;
 27  
 import freemarker.template.TemplateHashModel;
 28  
 import freemarker.template.TemplateModelException;
 29  
 
 30  
 import static org.jbehave.core.steps.StepCreator.PARAMETER_TABLE_END;
 31  
 import static org.jbehave.core.steps.StepCreator.PARAMETER_TABLE_START;
 32  
 import static org.jbehave.core.steps.StepCreator.PARAMETER_VALUE_END;
 33  
 import static org.jbehave.core.steps.StepCreator.PARAMETER_VALUE_START;
 34  
 
 35  
 /**
 36  
  * <p>
 37  
  * Story reporter that outputs to a template.
 38  
  * </p>
 39  
  */
 40  
 public class TemplateableOutput implements StoryReporter {
 41  
 
 42  
     private final File file;
 43  
     private final Keywords keywords;
 44  
     private final TemplateProcessor processor;
 45  
     private final String templatePath;
 46  2
     private OutputStory outputStory = new OutputStory();
 47  2
     private OutputScenario outputScenario = new OutputScenario();
 48  
     private OutputStep failedStep;
 49  
 
 50  2
     public TemplateableOutput(File file, Keywords keywords, TemplateProcessor processor, String templatePath) {
 51  2
         this.file = file;
 52  2
         this.keywords = keywords;
 53  2
         this.processor = processor;
 54  2
         this.templatePath = templatePath;
 55  2
     }
 56  
 
 57  
     public void storyNotAllowed(Story story, String filter) {
 58  0
         this.outputStory.notAllowedBy = filter;
 59  0
     }
 60  
 
 61  
     public void beforeStory(Story story, boolean givenStory) {
 62  2
         if (!givenStory) {
 63  2
             this.outputStory = new OutputStory();
 64  2
             this.outputStory.description = story.getDescription().asString();
 65  2
             this.outputStory.path = story.getPath();
 66  
         }
 67  2
         if (!story.getMeta().isEmpty()) {
 68  2
             this.outputStory.meta = new OutputMeta(story.getMeta());
 69  
         }
 70  2
     }
 71  
 
 72  
     public void narrative(Narrative narrative) {
 73  2
         if (!narrative.isEmpty()) {
 74  2
             this.outputStory.narrative = new OutputNarrative(narrative);
 75  
         }
 76  2
     }
 77  
 
 78  
     public void scenarioNotAllowed(Scenario scenario, String filter) {
 79  0
         this.outputScenario.notAllowedBy = filter;
 80  0
     }
 81  
 
 82  
     public void beforeScenario(String title) {
 83  4
         if (this.outputScenario.currentExample == null) {
 84  4
             this.outputScenario = new OutputScenario();
 85  
         }
 86  4
         this.outputScenario.title = title;
 87  4
     }
 88  
 
 89  
     public void beforeStep(String step) {
 90  0
     }
 91  
 
 92  
     public void successful(String step) {
 93  22
         this.outputScenario.addStep(new OutputStep(step, "successful"));
 94  22
     }
 95  
 
 96  
     public void ignorable(String step) {
 97  2
         this.outputScenario.addStep(new OutputStep(step, "ignorable"));
 98  2
     }
 99  
 
 100  
     public void pending(String step) {
 101  0
         this.outputScenario.addStep(new OutputStep(step, "pending"));
 102  0
     }
 103  
 
 104  
     public void notPerformed(String step) {
 105  2
         this.outputScenario.addStep(new OutputStep(step, "notPerformed"));
 106  2
     }
 107  
 
 108  
     public void failed(String step, Throwable storyFailure) {
 109  6
         this.failedStep = new OutputStep(step, "failed");
 110  6
         failedStep.failure = storyFailure;
 111  6
         this.outputScenario.addStep(failedStep);
 112  6
     }
 113  
 
 114  
     public void failedOutcomes(String step, OutcomesTable table) {
 115  2
         failed(step, table.failureCause());
 116  2
         this.failedStep.outcomes = table;
 117  2
     }
 118  
 
 119  
     public void givenStories(GivenStories givenStories) {
 120  2
         if (!givenStories.getStories().isEmpty()) {
 121  2
             this.outputScenario.givenStories = givenStories;
 122  
         }
 123  2
     }
 124  
 
 125  
     public void givenStories(List<String> storyPaths) {
 126  2
         givenStories(new GivenStories(StringUtils.join(storyPaths, ",")));
 127  2
     }
 128  
 
 129  
     public void scenarioMeta(Meta meta) {
 130  0
         if (!meta.isEmpty()) {
 131  0
             this.outputScenario.meta = new OutputMeta(meta);
 132  
         }
 133  0
     }
 134  
 
 135  
     public void beforeExamples(List<String> steps, ExamplesTable table) {
 136  2
         this.outputScenario.examplesSteps = steps;
 137  2
         this.outputScenario.examplesTable = table;
 138  2
     }
 139  
 
 140  
     public void example(Map<String, String> parameters) {
 141  4
         this.outputScenario.examples.add(parameters);
 142  4
         this.outputScenario.currentExample = parameters;
 143  4
     }
 144  
 
 145  
     public void afterExamples() {
 146  2
         this.outputScenario.currentExample = null;
 147  2
     }
 148  
 
 149  
     public void dryRun() {
 150  2
     }
 151  
 
 152  
     public void afterScenario() {
 153  4
         if (this.outputScenario.currentExample == null) {
 154  4
             this.outputStory.scenarios.add(outputScenario);
 155  
         }
 156  4
     }
 157  
 
 158  
     public void pendingMethods(List<String> methods) {
 159  2
         this.outputStory.pendingMethods = methods;
 160  2
     }
 161  
 
 162  
     public void restarted(String step, Throwable cause) {
 163  2
         this.outputScenario.addStep(new OutputRestart(step, cause.getMessage()));
 164  2
     }
 165  
 
 166  
     public void storyCancelled(Story story, StoryDuration storyDuration) {
 167  2
         this.outputStory.cancelled = true;
 168  2
         this.outputStory.storyDuration = storyDuration;
 169  2
     }
 170  
 
 171  
     public void afterStory(boolean givenStory) {
 172  2
         if (!givenStory) {
 173  2
             Map<String, Object> model = newDataModel();
 174  2
             model.put("story", outputStory);
 175  2
             model.put("keywords", new OutputKeywords(keywords));
 176  
 
 177  2
             BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
 178  2
             TemplateHashModel enumModels = wrapper.getEnumModels();
 179  
             TemplateHashModel escapeEnums;
 180  
             try {
 181  2
                 String escapeModeEnum = EscapeMode.class.getCanonicalName();
 182  2
                 escapeEnums = (TemplateHashModel) enumModels.get(escapeModeEnum);
 183  2
                 model.put("EscapeMode", escapeEnums);  
 184  0
             } catch (TemplateModelException e) {
 185  0
                 throw new IllegalArgumentException(e);
 186  2
             }  
 187  
 
 188  2
             write(file, templatePath, model);
 189  
         }
 190  2
     }
 191  
 
 192  
     private File write(File file, String resource, Map<String, Object> dataModel) {
 193  
         try {
 194  2
             file.getParentFile().mkdirs();
 195  2
             Writer writer = new FileWriter(file);
 196  2
             processor.process(resource, dataModel, writer);
 197  2
             return file;
 198  0
         } catch (Exception e) {
 199  0
             throw new RuntimeException(resource, e);
 200  
         }
 201  
     }
 202  
 
 203  
     private Map<String, Object> newDataModel() {
 204  2
         return new HashMap<String, Object>();
 205  
     }
 206  
 
 207  
     public static class OutputKeywords {
 208  
 
 209  
         private final Keywords keywords;
 210  
 
 211  2
         public OutputKeywords(Keywords keywords) {
 212  2
             this.keywords = keywords;
 213  2
         }
 214  
 
 215  
         public String getMeta() {
 216  1
             return keywords.meta();
 217  
         }
 218  
 
 219  
         public String getMetaProperty() {
 220  4
             return keywords.metaProperty();
 221  
         }
 222  
 
 223  
         public String getNarrative() {
 224  2
             return keywords.narrative();
 225  
         }
 226  
 
 227  
         public String getInOrderTo() {
 228  2
             return keywords.inOrderTo();
 229  
         }
 230  
 
 231  
         public String getAsA() {
 232  2
             return keywords.asA();
 233  
         }
 234  
 
 235  
         public String getiWantTo() {
 236  2
             return keywords.iWantTo();
 237  
         }
 238  
 
 239  
         public String getScenario() {
 240  4
             return keywords.scenario();
 241  
         }
 242  
 
 243  
         public String getGivenStories() {
 244  2
             return keywords.givenStories();
 245  
         }
 246  
 
 247  
         public String getExamplesTable() {
 248  2
             return keywords.examplesTable();
 249  
         }
 250  
 
 251  
         public String getExamplesTableRow() {
 252  4
             return keywords.examplesTableRow();
 253  
         }
 254  
 
 255  
         public String getExamplesTableHeaderSeparator() {
 256  0
             return keywords.examplesTableHeaderSeparator();
 257  
         }
 258  
 
 259  
         public String getExamplesTableValueSeparator() {
 260  0
             return keywords.examplesTableValueSeparator();
 261  
         }
 262  
 
 263  
         public String getExamplesTableIgnorableSeparator() {
 264  0
             return keywords.examplesTableIgnorableSeparator();
 265  
         }
 266  
 
 267  
         public String getGiven() {
 268  0
             return keywords.given();
 269  
         }
 270  
 
 271  
         public String getWhen() {
 272  0
             return keywords.when();
 273  
         }
 274  
 
 275  
         public String getThen() {
 276  0
             return keywords.then();
 277  
         }
 278  
 
 279  
         public String getAnd() {
 280  0
             return keywords.and();
 281  
         }
 282  
 
 283  
         public String getIgnorable() {
 284  0
             return keywords.ignorable();
 285  
         }
 286  
 
 287  
         public String getPending() {
 288  0
             return keywords.pending();
 289  
         }
 290  
 
 291  
         public String getNotPerformed() {
 292  1
             return keywords.notPerformed();
 293  
         }
 294  
 
 295  
         public String getFailed() {
 296  3
             return keywords.failed();
 297  
         }
 298  
 
 299  
         public String getDryRun() {
 300  0
             return keywords.dryRun();
 301  
         }
 302  
 
 303  
         public String getStoryCancelled() {
 304  2
             return keywords.storyCancelled();
 305  
         }
 306  
 
 307  
         public String getDuration() {
 308  2
             return keywords.duration();
 309  
         }
 310  
 
 311  
         public String getYes() {
 312  0
             return keywords.yes();
 313  
         }
 314  
 
 315  
         public String getNo() {
 316  4
             return keywords.no();
 317  
         }
 318  
     }
 319  
 
 320  22
     public static class OutputStory {
 321  
         private String description;
 322  
         private String path;
 323  
         private OutputMeta meta;
 324  
         private OutputNarrative narrative;
 325  
         private String notAllowedBy;
 326  
         private List<String> pendingMethods;
 327  4
         private List<OutputScenario> scenarios = new ArrayList<OutputScenario>();
 328  
         private boolean cancelled;
 329  
         private StoryDuration storyDuration;
 330  
 
 331  
         public String getDescription() {
 332  2
             return description;
 333  
         }
 334  
 
 335  
         public String getPath() {
 336  2
             return path;
 337  
         }
 338  
 
 339  
         public OutputMeta getMeta() {
 340  4
             return meta;
 341  
         }
 342  
 
 343  
         public OutputNarrative getNarrative() {
 344  4
             return narrative;
 345  
         }
 346  
 
 347  
         public String getNotAllowedBy() {
 348  0
             return notAllowedBy;
 349  
         }
 350  
 
 351  
         public List<String> getPendingMethods() {
 352  4
             return pendingMethods;
 353  
         }
 354  
 
 355  
         public List<OutputScenario> getScenarios() {
 356  2
             return scenarios;
 357  
         }
 358  
 
 359  
         public boolean isCancelled() {
 360  2
             return cancelled;
 361  
         }
 362  
 
 363  
         public StoryDuration getStoryDuration() {
 364  2
             return storyDuration;
 365  
         }
 366  
     }
 367  
 
 368  
     public static class OutputMeta {
 369  
 
 370  
         private final Meta meta;
 371  
 
 372  2
         public OutputMeta(Meta meta) {
 373  2
             this.meta = meta;
 374  2
         }
 375  
 
 376  
         public Map<String, String> getProperties() {
 377  2
             Map<String, String> properties = new HashMap<String, String>();
 378  2
             for (String name : meta.getPropertyNames()) {
 379  4
                 properties.put(name, meta.getProperty(name));
 380  
             }
 381  2
             return properties;
 382  
         }
 383  
 
 384  
     }
 385  
 
 386  
     public static class OutputNarrative {
 387  
         private final Narrative narrative;
 388  
 
 389  2
         public OutputNarrative(Narrative narrative) {
 390  2
             this.narrative = narrative;
 391  2
         }
 392  
 
 393  
         public String getInOrderTo() {
 394  2
             return narrative.inOrderTo();
 395  
         }
 396  
 
 397  
         public String getAsA() {
 398  2
             return narrative.asA();
 399  
         }
 400  
 
 401  
         public String getiWantTo() {
 402  2
             return narrative.iWantTo();
 403  
         }
 404  
 
 405  
     }
 406  
 
 407  34
     public static class OutputScenario {
 408  
         private String title;
 409  6
         private List<OutputStep> steps = new ArrayList<OutputStep>();
 410  
         private OutputMeta meta;
 411  
         private GivenStories givenStories;
 412  
         private String notAllowedBy;
 413  
         private List<String> examplesSteps;
 414  
         private ExamplesTable examplesTable;
 415  
         private Map<String, String> currentExample;
 416  6
         private List<Map<String, String>> examples = new ArrayList<Map<String, String>>();
 417  6
         private Map<Map<String, String>, List<OutputStep>> stepsByExample = new HashMap<Map<String, String>, List<OutputStep>>();
 418  
 
 419  
         public String getTitle() {
 420  4
             return title;
 421  
         }
 422  
 
 423  
         public void addStep(OutputStep outputStep) {
 424  34
             if (examplesTable == null) {
 425  24
                 steps.add(outputStep);
 426  
             } else {
 427  10
                 List<OutputStep> currentExampleSteps = stepsByExample.get(currentExample);
 428  10
                 if (currentExampleSteps == null) {
 429  4
                     currentExampleSteps = new ArrayList<OutputStep>();
 430  4
                     stepsByExample.put(currentExample, currentExampleSteps);
 431  
                 }
 432  10
                 currentExampleSteps.add(outputStep);
 433  
             }
 434  34
         }
 435  
 
 436  
         public List<OutputStep> getSteps() {
 437  2
             return steps;
 438  
         }
 439  
 
 440  
         public List<OutputStep> getStepsByExample(Map<String, String> example) {
 441  4
             List<OutputStep> steps = stepsByExample.get(example);
 442  4
             if (steps == null) {
 443  0
                 return new ArrayList<OutputStep>();
 444  
             }
 445  4
             return steps;
 446  
         }
 447  
 
 448  
         public OutputMeta getMeta() {
 449  4
             return meta;
 450  
         }
 451  
 
 452  
         public GivenStories getGivenStories() {
 453  6
             return givenStories;
 454  
         }
 455  
 
 456  
         public String getNotAllowedBy() {
 457  0
             return notAllowedBy;
 458  
         }
 459  
 
 460  
         public List<String> getExamplesSteps() {
 461  2
             return examplesSteps;
 462  
         }
 463  
 
 464  
         public ExamplesTable getExamplesTable() {
 465  6
             return examplesTable;
 466  
         }
 467  
 
 468  
         public List<Map<String, String>> getExamples() {
 469  4
             return examples;
 470  
         }
 471  
     }
 472  
 
 473  
     public static class OutputRestart extends OutputStep {
 474  
 
 475  
         public OutputRestart(String step, String outcome) {
 476  2
             super(step, outcome);
 477  2
         }
 478  
 
 479  
     }
 480  
 
 481  8
     public static class OutputStep {
 482  
         private final String step;
 483  
         private final String outcome;
 484  
         private Throwable failure;
 485  
         private OutcomesTable outcomes;
 486  
         private List<OutputParameter> parameters;
 487  
         private String stepPattern;
 488  
         private String tableAsString;
 489  
         private ExamplesTable table;
 490  
 
 491  34
         public OutputStep(String step, String outcome) {
 492  34
             this.step = step;
 493  34
             this.outcome = outcome;
 494  34
             parseTableAsString();
 495  34
             parseParameters();
 496  34
             createStepPattern();
 497  34
         }
 498  
 
 499  
         public String getStep() {
 500  0
             return step;
 501  
         }
 502  
 
 503  
         public String getStepPattern() {
 504  0
             return stepPattern;
 505  
         }
 506  
 
 507  
         public List<OutputParameter> getParameters() {
 508  0
             return parameters;
 509  
         }
 510  
 
 511  
         public String getOutcome() {
 512  51
             return outcome;
 513  
         }
 514  
 
 515  
         public Throwable getFailure() {
 516  34
             return failure;
 517  
         }
 518  
 
 519  
         public String getFailureCause() {
 520  6
             if (failure != null) {
 521  6
                 return new StackTraceFormatter(true).stackTrace(failure);
 522  
             }
 523  0
             return "";
 524  
         }
 525  
 
 526  
         public ExamplesTable getTable() {
 527  34
             return table;
 528  
         }
 529  
 
 530  
         public OutcomesTable getOutcomes() {
 531  36
             return outcomes;
 532  
         }
 533  
 
 534  
         public String getOutcomesFailureCause() {
 535  2
             if (outcomes.failureCause() != null) {
 536  2
                 return new StackTraceFormatter(true).stackTrace(outcomes.failureCause());
 537  
             }
 538  0
             return "";
 539  
         }
 540  
 
 541  
         /*
 542  
          * formatting without escaping doesn't make sense unless
 543  
          * we do a ftl text output format
 544  
          */
 545  
         @Deprecated
 546  
         public String getFormattedStep(String parameterPattern) {
 547  0
             return getFormattedStep(EscapeMode.NONE, parameterPattern);
 548  
         }
 549  
 
 550  
         public String getFormattedStep(EscapeMode outputFormat, String parameterPattern) {
 551  
             // note that escaping the stepPattern string only works
 552  
             // because placeholders for parameters do not contain
 553  
             // special chars (the placeholder is {0} etc)
 554  34
             String escapedStep = escapeString(outputFormat, stepPattern);
 555  34
             if (!parameters.isEmpty()) {
 556  
                 try {
 557  6
                     return MessageFormat.format(escapedStep, formatParameters(outputFormat, parameterPattern));
 558  0
                 } catch (RuntimeException e) {
 559  0
                     throw new StepFormattingFailed(stepPattern, parameterPattern, parameters, e);
 560  
                 }
 561  
             }
 562  28
             return escapedStep;
 563  
         }
 564  
 
 565  
         private String escapeString(EscapeMode outputFormat, String string) {
 566  42
             if(outputFormat==EscapeMode.HTML) {
 567  21
                 return StringEscapeUtils.escapeHtml(string);
 568  21
             } else if(outputFormat==EscapeMode.XML) {
 569  21
                 return StringEscapeUtils.escapeXml(string);
 570  
             } else {
 571  0
                 return string;
 572  
             }
 573  
         }
 574  
 
 575  
         private Object[] formatParameters(EscapeMode outputFormat, String parameterPattern) {
 576  6
             Object[] arguments = new Object[parameters.size()];
 577  14
             for (int a = 0; a < parameters.size(); a++) {
 578  8
                 arguments[a] = MessageFormat.format(parameterPattern, escapeString(outputFormat, parameters.get(a).getValue()));
 579  
             }
 580  6
             return arguments;
 581  
         }
 582  
 
 583  
         private void parseParameters() {
 584  
             // first, look for parameterized scenarios
 585  34
             parameters = findParameters(PARAMETER_VALUE_START + PARAMETER_VALUE_START, PARAMETER_VALUE_END
 586  
                     + PARAMETER_VALUE_END);
 587  
             // second, look for normal scenarios
 588  34
             if (parameters.isEmpty()) {
 589  34
                 parameters = findParameters(PARAMETER_VALUE_START, PARAMETER_VALUE_END);
 590  
             }
 591  34
         }
 592  
 
 593  
         private List<OutputParameter> findParameters(String start, String end) {
 594  68
             List<OutputParameter> parameters = new ArrayList<OutputParameter>();
 595  68
             Matcher matcher = Pattern.compile("(" + start + ".*?" + end + ")(\\W|\\Z)",
 596  
                     Pattern.DOTALL).matcher(step);
 597  76
             while (matcher.find()) {
 598  8
                 parameters.add(new OutputParameter(step, matcher.start(), matcher.end()));
 599  
             }
 600  68
             return parameters;
 601  
         }
 602  
 
 603  
         private void parseTableAsString() {
 604  34
             if (step.contains(PARAMETER_TABLE_START) && step.contains(PARAMETER_TABLE_END)) {
 605  0
                 tableAsString = StringUtils.substringBetween(step, PARAMETER_TABLE_START, PARAMETER_TABLE_END);
 606  0
                 table = new ExamplesTable(tableAsString);
 607  
             }
 608  34
         }
 609  
 
 610  
         private void createStepPattern() {
 611  34
             this.stepPattern = step;
 612  34
             if (tableAsString != null) {
 613  0
                 this.stepPattern = StringUtils.replaceOnce(stepPattern, PARAMETER_TABLE_START + tableAsString
 614  
                         + PARAMETER_TABLE_END, "");
 615  
             }
 616  42
             for (int count = 0; count < parameters.size(); count++) {
 617  8
                 String value = parameters.get(count).toString();
 618  8
                 this.stepPattern = stepPattern.replace(value, "{" + count + "}");
 619  
             }
 620  34
         }
 621  
 
 622  
         @SuppressWarnings("serial")
 623  
         public static class StepFormattingFailed extends RuntimeException {
 624  
 
 625  
             public StepFormattingFailed(String stepPattern, String parameterPattern, List<OutputParameter> parameters,
 626  
                     RuntimeException cause) {
 627  0
                 super("Failed to format step '" + stepPattern + "' with parameter pattern '" + parameterPattern
 628  
                         + "' and parameters: " + parameters, cause);
 629  0
             }
 630  
 
 631  
         }
 632  
 
 633  
     }
 634  
 
 635  
     public static class OutputParameter {
 636  
         private final String parameter;
 637  
 
 638  8
         public OutputParameter(String pattern, int start, int end) {
 639  8
             this.parameter = pattern.substring(start, end).trim();
 640  8
         }
 641  
 
 642  
         public String getValue() {
 643  8
             String value = StringUtils.remove(parameter, PARAMETER_VALUE_START);
 644  8
             value = StringUtils.remove(value, PARAMETER_VALUE_END);
 645  8
             return value;
 646  
         }
 647  
 
 648  
         @Override
 649  
         public String toString() {
 650  8
             return parameter;
 651  
         }
 652  
     }
 653  
 
 654  
 }