001: /*
002: * ====================================================================
003: *
004: * The Apache Software License, Version 1.1
005: *
006: * Copyright (c) 1999-2003 The Apache Software Foundation.
007: * All rights reserved.
008: *
009: * Redistribution and use in source and binary forms, with or without
010: * modification, are permitted provided that the following conditions
011: * are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowledgement:
023: * "This product includes software developed by the
024: * Apache Software Foundation (http://www.apache.org/)."
025: * Alternately, this acknowledgement may appear in the software itself,
026: * if and wherever such third-party acknowledgements normally appear.
027: *
028: * 4. The names "The Jakarta Project", "Commons", and "Apache Software
029: * Foundation" must not be used to endorse or promote products derived
030: * from this software without prior written permission. For written
031: * permission, please contact apache@apache.org.
032: *
033: * 5. Products derived from this software may not be called "Apache"
034: * nor may "Apache" appear in their names without prior written
035: * permission of the Apache Software Foundation.
036: *
037: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
038: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
039: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
040: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
041: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
042: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
043: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
044: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
045: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
046: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
047: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
048: * SUCH DAMAGE.
049: * ====================================================================
050: *
051: * This software consists of voluntary contributions made by many
052: * individuals on behalf of the Apache Software Foundation. For more
053: * information on the Apache Software Foundation, please see
054: * <http://www.apache.org/>.
055: *
056: */
057:
058: package org.apache.commons.jrcs.rcs;
059:
060: import java.text.Format;
061: import java.text.MessageFormat;
062:
063: import org.apache.oro.text.regex.*;
064:
065: /**
066: * Formatter for the RCS keywords. It is intended as an helper class to
067: * replace the use of gnu.regexp. This class is NOT threadsafe.
068: *
069: * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
070: */
071: final class KeywordsFormat {
072: //WARNING: Do not remove the string concatenations
073: // or CVS will mangle the strings on check in/out.
074: final Format Header_FORMAT = new MessageFormat("$"
075: + "Header: {1} {2} {3, date,yyyy/MM/dd HH:mm:ss} {4} {5} "
076: + "$");
077: final Format Id_FORMAT = new MessageFormat("$"
078: + "Id: {1} {2} {3, date,yyyy/MM/dd HH:mm:ss} {4} {5} "
079: + "$");
080: final Format RCSFile_FORMAT = new MessageFormat("$"
081: + "RCSfile: {1} " + "$");
082: final Format Revision_FORMAT = new MessageFormat("$"
083: + "Revision: {2} " + "$");
084: final Format Date_FORMAT = new MessageFormat("$"
085: + "Date: {3, date,yyyy/MM/dd HH:mm:ss} " + "$");
086: final Format Author_FORMAT = new MessageFormat("$" + "Author: {4} "
087: + "$");
088: final Format State_FORMAT = new MessageFormat("$" + "State: {5} "
089: + "$");
090: final Format Locker_FORMAT = new MessageFormat("$" + "Locker: {6} "
091: + "$");
092: final Format Source_FORMAT = new MessageFormat("$" + "Source: {0} "
093: + "$");
094:
095: private final Pattern ID_RE;
096: private final Pattern HEADER_RE;
097: private final Pattern SOURCE_RE;
098: private final Pattern RCSFILE_RE;
099: private final Pattern REVISION_RE;
100: private final Pattern DATE_RE;
101: private final Pattern AUTHOR_RE;
102: private final Pattern STATE_RE;
103: private final Pattern LOCKER_RE;
104:
105: /** the substitution instance to be reused */
106: private final StringSubstitution subst = new StringSubstitution();
107:
108: KeywordsFormat() {
109: try {
110: Perl5Compiler compiler = new Perl5Compiler();
111: ID_RE = compiler.compile("\\$Id(:[^\\$]*)?\\$");
112: HEADER_RE = compiler.compile("\\$Header(:[^\\$]*)?\\$");
113: SOURCE_RE = compiler.compile("\\$Source(:[^\\$]*)?\\$");
114: RCSFILE_RE = compiler.compile("\\$RCSfile(:[^\\$]*)?\\$");
115: REVISION_RE = compiler.compile("\\$Revision(:[^\\$]*)?\\$");
116: DATE_RE = compiler.compile("\\$Date(:[^\\$]*)?\\$");
117: AUTHOR_RE = compiler.compile("\\$Author(:[^\\$]*)?\\$");
118: STATE_RE = compiler.compile("\\$State(:[^\\$]*)?\\$");
119: LOCKER_RE = compiler.compile("\\$Locker(:[^\\$]*)?\\$");
120: } catch (MalformedPatternException e) {
121: throw new ExceptionInInitializerError(e);
122: }
123: }
124:
125: /** the matcher used for replacement */
126: private final Perl5Matcher matcher = new Perl5Matcher();
127:
128: /**
129: * update the given text made of RCS keywords with the appropriate
130: * revision info.
131: * @param text the input text containing the RCS keywords.
132: * @param revisionInfo the revision information.
133: * @return the formatted text with the RCS keywords.
134: */
135: String update(String text, Object[] revisionInfo) {
136: String data = text;
137: data = substitute(data, ID_RE, Id_FORMAT.format(revisionInfo));
138: data = substitute(data, HEADER_RE, Header_FORMAT
139: .format(revisionInfo));
140: data = substitute(data, SOURCE_RE, Source_FORMAT
141: .format(revisionInfo));
142: data = substitute(data, RCSFILE_RE, RCSFile_FORMAT
143: .format(revisionInfo));
144: data = substitute(data, REVISION_RE, Revision_FORMAT
145: .format(revisionInfo));
146: data = substitute(data, DATE_RE, Date_FORMAT
147: .format(revisionInfo));
148: data = substitute(data, AUTHOR_RE, Author_FORMAT
149: .format(revisionInfo));
150: data = substitute(data, STATE_RE, State_FORMAT
151: .format(revisionInfo));
152: data = substitute(data, LOCKER_RE, Locker_FORMAT
153: .format(revisionInfo));
154: //@TODO: should do something about Name and Log
155: return data;
156: }
157:
158: /**
159: * Reinitialize all RCS keywords match.
160: * @param text the text to look for RCS keywords.
161: * @return the text with initialized RCS keywords.
162: */
163: String reset(String text) {
164: //WARNING: Do not remove the string concatenations
165: // or CVS will mangle the strings on check in/out.
166: String data = text;
167: data = substitute(data, ID_RE, '$' + "Id$");
168: data = substitute(data, HEADER_RE, '$' + "Header$");
169: data = substitute(data, SOURCE_RE, '$' + "Source$");
170: data = substitute(data, RCSFILE_RE, '$' + "RCSfile$");
171: data = substitute(data, REVISION_RE, '$' + "Revision$");
172: data = substitute(data, DATE_RE, '$' + "Date$");
173: data = substitute(data, AUTHOR_RE, '$' + "Author$");
174: data = substitute(data, STATE_RE, '$' + "State$");
175: data = substitute(data, LOCKER_RE, '$' + "Locker$");
176: //@TODO: should do something about Name and Log
177: return data;
178: }
179:
180: /**
181: * Helper method for substitution that will substitute all matches of
182: * a given pattern.
183: * @param input the text to look for substitutions.
184: * @param pattern the pattern to replace in the input text.
185: * @param substitution the string to use as a replacement for the pattern.
186: * @return the text with the subsituted value.
187: */
188: private final String substitute(String input, Pattern pattern,
189: String substitution) {
190: subst.setSubstitution(substitution);
191: final String output = Util.substitute(matcher, pattern, subst,
192: input, Util.SUBSTITUTE_ALL);
193: // no need to keep a reference to the last substitution string
194: subst.setSubstitution("");
195: return output;
196: }
197:
198: }
|