2 Copyright (C) 2003 Morten O. Alver
3 All programs in this directory and
4 subdirectories are published under the GNU General Public License as
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 Further information about the GNU GPL is available at:
23 http://www.gnu.org/copyleft/gpl.ja.html
26 package net.sf.jabref.export.layout;
28 import java.util.ArrayList;
30 import java.util.Vector;
32 import net.sf.jabref.BibtexDatabase;
33 import net.sf.jabref.BibtexEntry;
34 import net.sf.jabref.Globals;
35 import net.sf.jabref.NameFormatterTab;
36 import net.sf.jabref.Util;
37 import net.sf.jabref.export.layout.format.NameFormat;
38 import wsi.ra.tool.WSITools;
39 import wsi.ra.types.StringInt;
45 * @version $Revision: 2301 $
47 public class LayoutEntry {
49 // ////////////////////////////////////////////////////////
51 private LayoutFormatter[] option;
55 private LayoutEntry[] layoutEntries;
59 private String classPrefix;
62 // ///////////////////////////////////////////////////////////
64 public LayoutEntry(StringInt si, String classPrefix_) throws Exception {
66 classPrefix = classPrefix_;
68 if (si.i == LayoutHelper.IS_LAYOUT_TEXT) {
70 } else if (si.i == LayoutHelper.IS_SIMPLE_FIELD) {
72 } else if (si.i == LayoutHelper.IS_FIELD_START) {
73 } else if (si.i == LayoutHelper.IS_FIELD_END) {
74 } else if (si.i == LayoutHelper.IS_OPTION_FIELD) {
75 Vector v = new Vector();
76 WSITools.tokenize(v, si.s, "\n");
79 text = (String) v.get(0);
81 text = ((String) v.get(0)).trim();
85 option = getOptionalLayout((String) v.get(1), classPrefix);
87 // catch (Exception e)
89 // e.printStackTrace();
94 // else if (si.i == LayoutHelper.IS_OPTION_FIELD_PARAM)
99 public LayoutEntry(Vector parsedEntries, String classPrefix_, int layoutType) throws Exception {
100 classPrefix = classPrefix_;
101 String blockStart = null;
102 String blockEnd = null;
104 Vector<StringInt> blockEntries = null;
105 Vector<LayoutEntry> tmpEntries = new Vector<LayoutEntry>();
107 si = (StringInt) parsedEntries.get(0);
109 si = (StringInt) parsedEntries.get(parsedEntries.size() - 1);
112 if (!blockStart.equals(blockEnd)) {
113 System.err.println("Field start and end entry must be equal.");
119 for (int i = 1; i < (parsedEntries.size() - 1); i++) {
120 si = (StringInt) parsedEntries.get(i);
122 // System.out.println("PARSED-ENTRY: "+si.s+"="+si.i);
123 if (si.i == LayoutHelper.IS_LAYOUT_TEXT) {
124 } else if (si.i == LayoutHelper.IS_SIMPLE_FIELD) {
125 } else if ((si.i == LayoutHelper.IS_FIELD_START)
126 || (si.i == LayoutHelper.IS_GROUP_START)) {
127 blockEntries = new Vector<StringInt>();
129 } else if ((si.i == LayoutHelper.IS_FIELD_END) || (si.i == LayoutHelper.IS_GROUP_END)) {
130 if (blockStart.equals(si.s)) {
131 blockEntries.add(si);
132 if (si.i == LayoutHelper.IS_GROUP_END)
133 le = new LayoutEntry(blockEntries, classPrefix, LayoutHelper.IS_GROUP_START);
135 le = new LayoutEntry(blockEntries, classPrefix, LayoutHelper.IS_FIELD_START);
139 System.out.println("Nested field entries are not implemented !!!");
141 } else if (si.i == LayoutHelper.IS_OPTION_FIELD) {
144 // else if (si.i == LayoutHelper.IS_OPTION_FIELD_PARAM)
147 if (blockEntries == null) {
148 // System.out.println("BLOCK ADD: "+si.s+"="+si.i);
149 tmpEntries.add(new LayoutEntry(si, classPrefix));
151 blockEntries.add(si);
155 layoutEntries = new LayoutEntry[tmpEntries.size()];
157 for (int i = 0; i < tmpEntries.size(); i++) {
158 layoutEntries[i] = (LayoutEntry) tmpEntries.get(i);
160 // System.out.println(layoutEntries[i].text);
164 public String doLayout(BibtexEntry bibtex, BibtexDatabase database) {
167 case LayoutHelper.IS_LAYOUT_TEXT:
169 case LayoutHelper.IS_SIMPLE_FIELD:
170 return BibtexDatabase.getResolvedField(text, bibtex, database);
171 case LayoutHelper.IS_FIELD_START:
172 case LayoutHelper.IS_GROUP_START: {
173 String field = BibtexDatabase.getResolvedField(text, bibtex, database);
176 || ((type == LayoutHelper.IS_GROUP_START) && (field.equalsIgnoreCase(LayoutHelper
177 .getCurrentGroup())))) {
180 if (type == LayoutHelper.IS_GROUP_START) {
181 LayoutHelper.setCurrentGroup(field);
183 StringBuffer sb = new StringBuffer(100);
185 boolean previousSkipped = false;
187 for (int i = 0; i < layoutEntries.length; i++) {
188 fieldText = layoutEntries[i].doLayout(bibtex, database);
190 if (fieldText == null) {
191 if ((i + 1) < layoutEntries.length) {
192 if (layoutEntries[i + 1].doLayout(bibtex, database).trim().length() == 0) {
194 previousSkipped = true;
199 // if previous was skipped --> remove leading line
201 if (previousSkipped) {
204 while ((eol < fieldText.length())
205 && ((fieldText.charAt(eol) == '\n') || (fieldText.charAt(eol) == '\r'))) {
209 if (eol < fieldText.length()) {
210 sb.append(fieldText.substring(eol));
213 // System.out.println("ENTRY-BLOCK: " +
214 // layoutEntries[i].doLayout(bibtex));
215 sb.append(fieldText);
219 previousSkipped = false;
222 return sb.toString();
225 case LayoutHelper.IS_FIELD_END:
226 case LayoutHelper.IS_GROUP_END:
228 case LayoutHelper.IS_OPTION_FIELD: {
231 if (text.equals("bibtextype")) {
232 fieldEntry = bibtex.getType().getName();
234 // changed section begin - arudert
235 // resolve field (recognized by leading backslash) or text
236 String field = text.startsWith("\\") ? BibtexDatabase.getResolvedField(text.substring(1), bibtex, database)
237 : BibtexDatabase.getText(text, database);
238 // changed section end - arudert
246 // System.out.println("OPTION: "+option);
247 if (option != null) {
248 for (int i = 0; i < option.length; i++) {
249 fieldEntry = option[i].format(fieldEntry);
255 case LayoutHelper.IS_ENCODING_NAME: {
256 // Printing the encoding name is not supported in entry layouts, only
257 // in begin/end layouts. This prevents breakage if some users depend
258 // on a field called "encoding". We simply return this field instead:
259 return BibtexDatabase.getResolvedField("encoding", bibtex, database);
266 // added section - begin (arudert)
268 * Do layout for general formatters (no bibtex-entry fields).
274 public String doLayout(BibtexDatabase database, String encoding) {
275 if (type == LayoutHelper.IS_LAYOUT_TEXT) {
277 } else if (type == LayoutHelper.IS_SIMPLE_FIELD) {
278 throw new UnsupportedOperationException(
279 "bibtex entry fields not allowed in begin or end layout");
280 } else if ((type == LayoutHelper.IS_FIELD_START) || (type == LayoutHelper.IS_GROUP_START)) {
281 throw new UnsupportedOperationException(
282 "field and group starts not allowed in begin or end layout");
283 } else if ((type == LayoutHelper.IS_FIELD_END) || (type == LayoutHelper.IS_GROUP_END)) {
284 throw new UnsupportedOperationException(
285 "field and group ends not allowed in begin or end layout");
286 } else if (type == LayoutHelper.IS_OPTION_FIELD) {
287 String field = BibtexDatabase.getText(text, database);
288 if (option != null) {
289 for (int i = 0; i < option.length; i++) {
290 field = option[i].format(field);
295 } else if (type == LayoutHelper.IS_ENCODING_NAME) {
301 // added section - end (arudert)
303 public static LayoutFormatter getLayoutFormatter(String className, String classPrefix)
305 LayoutFormatter f = null;
306 if (className.length() > 0) {
309 f = (LayoutFormatter) Class.forName(classPrefix + className).newInstance();
310 } catch (Throwable ex2) {
311 f = (LayoutFormatter) Class.forName(className).newInstance();
313 } catch (ClassNotFoundException ex) {
314 throw new Exception(Globals.lang("Formatter not found") + ": " + className);
315 } catch (InstantiationException ex) {
316 throw new Exception(className + " can not be instantiated.");
317 } catch (IllegalAccessException ex) {
318 throw new Exception(className + " can't be accessed.");
325 * Return an array of LayoutFormatters found in the given formatterName
326 * string (in order of appearance).
329 public static LayoutFormatter[] getOptionalLayout(String formatterName, String classPrefix)
332 ArrayList formatterStrings = Util.parseMethodsCalls(formatterName);
334 ArrayList<LayoutFormatter> results = new ArrayList<LayoutFormatter>(formatterStrings.size());
336 Map userNameFormatter = NameFormatterTab.getNameFormatters();
338 for (int i = 0; i < formatterStrings.size(); i++) {
340 String[] strings = (String[]) formatterStrings.get(i);
342 String className = strings[0].trim();
345 LayoutFormatter f = getLayoutFormatter(className, classPrefix);
346 // If this formatter accepts an argument, check if we have one, and
348 if (f instanceof ParamLayoutFormatter) {
349 if (strings.length >= 2)
350 ((ParamLayoutFormatter)f).setArgument(strings[1]);
353 } catch (Exception e) {
355 String formatterParameter = (String) userNameFormatter.get(className);
357 if (formatterParameter == null) {
358 throw new Exception(Globals.lang("Formatter not found") + ": " + className);
360 NameFormat nf = new NameFormat();
361 nf.setParameter(formatterParameter);
367 return (LayoutFormatter[]) results.toArray(new LayoutFormatter[] {});