Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (c) 2011, REMPL.com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3) Neither the name of the REMPL.com nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.rempl.readers.pdd;
// REMPL API classes
import com.rempl.api.Logger;
// antlr parser
import com.rempl.readers.pdd.puzzle.PuzzleLexer;
import com.rempl.readers.pdd.puzzle.PuzzleParser;
// utils
import com.rempl.utils.VelocityWriter;
// file management
import java.io.File;
// collections
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// regular expressions
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// ANTLR3 runtime for grammar/lexical processing
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.TokenStream;
// file management
import org.apache.commons.io.FileUtils;
/**
* Read puzzles from a file.
*
* @author Yegor Bugayenko ([email protected])
* @version $Id: FilePuzzles.java 795 2011-03-19 10:17:23Z [email protected] $
*/
public final class FilePuzzles {
/**
* The {@link File} to work with.
* @see #FilePuzzles(File)
*/
private final File file;
/**
* Public ctor.
* @param pfile The file to work with
*/
public FilePuzzles(final File pfile) {
this.file = pfile;
}
/**
* Convert file information to the UML.
* @return UML in string
* @throws java.io.IOException If I/O problem occurs
*/
public String uml() throws java.io.IOException {
if (Logger.isTraceEnabled(this)) {
Logger.trace(this, "#uml()");
}
final List lines = FileUtils.readLines(this.file);
final List puzzles = this.puzzles(lines);
if (Logger.isDebugEnabled(this)) {
for (Puzzle puzzle : puzzles) {
Logger.debug(
this,
"#uml(%s): puzzle found (#%s:%dmin by %s)",
this.file.getName(),
puzzle.getTicket(),
puzzle.getEstimate(),
puzzle.getOwnerTitle()
);
}
}
final Map ctx = new HashMap();
ctx.put("file", this.file);
ctx.put("puzzles", puzzles);
final String uml = VelocityWriter.INSTANCE
.write("vm/file-puzzles.vm", ctx);
if (Logger.isDebugEnabled(this)) {
Logger.debug(
this,
"#uml(): %d puzzles discovered in %s:\n%s",
puzzles.size(),
this.file.getName(),
uml
);
}
return uml;
}
/**
* Retrieve puzzles from the lines.
* @param lines List of input lines
* @return List of puzzles discovered
*/
public List puzzles(final List lines) {
final List puzzles = new ArrayList();
Puzzle puzzle = null;
Integer num = 0;
Integer started = num;
final Matcher matcher = this.matcher();
for (String line : lines) {
num += 1;
matcher.reset(line);
if (matcher.matches()) {
// the puzzle start is found, let's create a new object
// and add it immediately to the collection
puzzle = this.parse(line);
if (puzzle != null) {
// yes, it's not a mistake, the puzzle is found and
// perfectly parsed, now it goes to the collection
puzzles.add(puzzle);
started = num;
puzzle.setLines(started, started);
}
} else if (puzzle != null) {
// we're somewhere inside the puzzle found before,
// and this particular line has to go into it
// or has to stop the puzzle
if (line.startsWith(puzzle.getPrefix())) {
// yes, this line goes into the puzzle, and we
// continue working with the puzzle
puzzle.appendBody(
line.substring(puzzle.getPrefix().length())
);
} else {
// no, the line is not for this puzzle, we have
// to stop working with the puzzle and register
// it's location in the files (the lines)
puzzle.setLines(started, num - 1);
puzzle = null;
}
}
}
return puzzles;
}
/**
* Get RegEx matcher to match every line for puzzles.
* @return The matcher
* @see #puzzles(List)
*/
private Matcher matcher() {
final Pattern pattern = Pattern.compile(
// start of the line
"^"
// something before the @todo tag
+ "([\\W\\D]+\\s+|)"
// the tag itself
+ "@todo "
// the number of the ticket
+ "#(\\d+)"
// one of the following, followed by a space-char
+ "(/\\d+|:\\d+(\\.\\d+)?(hrs|hr|h|)|\\?|\\!)* "
// rest of the line
+ ".*"
// end of the line
+ "$"
);
return pattern.matcher("");
}
/**
* Make puzzle out of string.
* @param line One line in the input file
* @return The puzzle discovered or NULL if nothing found
*/
private Puzzle parse(final String line) {
final CharStream input = new ANTLRStringStream(line);
final PuzzleLexer lexer = new PuzzleLexer(input);
final TokenStream tokens = new CommonTokenStream(lexer);
final PuzzleParser parser = new PuzzleParser(tokens);
Puzzle puzzle;
try {
puzzle = parser.puzzle();
} catch (org.antlr.runtime.RecognitionException ex) {
puzzle = null;
} catch (PuzzleParsingException ex) {
puzzle = null;
}
if (Logger.isDebugEnabled(this)) {
Logger.debug(this, "#parse(%s)", line);
}
return puzzle;
}
}