001: /*
002: * Copyright 2006 JBoss Inc
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.drools.lang.dsl;
018:
019: import java.io.BufferedReader;
020: import java.io.IOException;
021: import java.io.Reader;
022: import java.io.Writer;
023: import java.util.Collections;
024: import java.util.Iterator;
025: import java.util.LinkedList;
026: import java.util.List;
027: import java.util.regex.Matcher;
028: import java.util.regex.Pattern;
029:
030: import org.drools.lang.dsl.DSLMappingEntry.DefaultDSLEntryMetaData;
031:
032: /**
033: * A helper class that handles a DSL Mapping file
034: * @author etirelli
035: */
036: public class DSLMappingFile {
037:
038: // the following pattern will be used to parse dsl mapping entries in the DSL file.
039: // It is capable of parsing entries that follows the pattern:
040: // [<section>][<metadata>]?<key>=<value>
041: private static final Pattern pattern = Pattern
042: .compile("((\\[[^\\[]*\\])\\s*(\\[([^\\[]*)\\])?)?\\s*([^=]*)=(.*)");
043: private static final String KEYWORD = "[keyword]";
044: private static final String CONDITION = "[condition]";
045: private static final String CONSEQUENCE = "[consequence]";
046: //private static final String ANY = "[*]";
047: private static final String WHEN = "[when]";
048: private static final String THEN = "[then]";
049:
050: private DSLMapping mapping;
051: private List errors;
052:
053: public DSLMappingFile() {
054: this .mapping = new DefaultDSLMapping();
055: this .errors = Collections.EMPTY_LIST;
056: }
057:
058: /**
059: * Returns the DSL mapping loaded from this file
060: * @return
061: */
062: public DSLMapping getMapping() {
063: return this .mapping;
064: }
065:
066: /**
067: * Sets the
068: * @param mapping
069: */
070: public void setMapping(final DSLMapping mapping) {
071: this .mapping = mapping;
072: }
073:
074: /**
075: * Returns the list of parsing errors
076: * @return
077: */
078: public List getErrors() {
079: return Collections.unmodifiableList(this .errors);
080: }
081:
082: /**
083: * Parses the file. Throws IOException in case there is any problem
084: * reading the file;
085: *
086: * @return true in case no error was found parsing the file. false
087: * otherwise. Use getErrors() to check for the actual errors.
088: */
089: public boolean parseAndLoad(final Reader dsl) throws IOException {
090: String line = null;
091: int linecounter = 0;
092: final BufferedReader dslFileReader = new BufferedReader(dsl);
093: this .mapping = new DefaultDSLMapping();
094: this .errors = new LinkedList();
095: while ((line = dslFileReader.readLine()) != null) {
096: linecounter++;
097: final Matcher mat = pattern.matcher(line);
098: if (mat.matches()) {
099: final String sectionStr = mat.group(2);
100: final String metadataStr = mat.group(4);
101: final String key = mat.group(5);
102: final String value = mat.group(6);
103:
104: DSLMappingEntry.Section section = DSLMappingEntry.ANY;
105: if (KEYWORD.equals(sectionStr)) {
106: section = DSLMappingEntry.KEYWORD;
107: } else if (CONDITION.equals(sectionStr)
108: || WHEN.equals(sectionStr)) {
109: section = DSLMappingEntry.CONDITION;
110: } else if (CONSEQUENCE.equals(sectionStr)
111: || THEN.equals(sectionStr)) {
112: section = DSLMappingEntry.CONSEQUENCE;
113: }
114:
115: DSLMappingEntry.MetaData metadata;
116: if (metadataStr == null || metadataStr.length() == 0) {
117: metadata = DSLMappingEntry.EMPTY_METADATA;
118: } else {
119: metadata = new DefaultDSLEntryMetaData(metadataStr);
120: }
121:
122: final DSLMappingEntry entry = new DefaultDSLMappingEntry(
123: section, metadata, key, value);
124:
125: this .mapping.addEntry(entry);
126: } else if (!line.trim().startsWith("#")) { // it is not a comment
127: final String error = "Error parsing mapping entry: "
128: + line;
129: final DSLMappingParseException exception = new DSLMappingParseException(
130: error, linecounter);
131: this .errors.add(exception);
132: }
133: }
134: return this .errors.isEmpty();
135: }
136:
137: /**
138: * Saves current mapping into a DSL mapping file
139: * @param out
140: * @throws IOException
141: */
142: public void saveMapping(final Writer out) throws IOException {
143: for (final Iterator it = this .mapping.getEntries().iterator(); it
144: .hasNext();) {
145: out.write(it.next().toString());
146: out.write("\n");
147: }
148: }
149:
150: /**
151: * Saves the given mapping into a DSL mapping file
152: *
153: * @param out
154: * @param mapping
155: * @throws IOException
156: */
157: public static void saveMapping(final Writer out,
158: final DSLMapping mapping) throws IOException {
159: for (final Iterator it = mapping.getEntries().iterator(); it
160: .hasNext();) {
161: out.write(it.next().toString());
162: out.write("\n");
163: }
164: }
165:
166: /**
167: * Method to return the current mapping as a String object
168: * @return
169: */
170: public String dumpFile() {
171: final StringBuffer buf = new StringBuffer();
172: for (final Iterator it = this .mapping.getEntries().iterator(); it
173: .hasNext();) {
174: buf.append(it.next());
175: buf.append("\n");
176: }
177: return buf.toString();
178: }
179:
180: }
|