001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.cocoon.components.elementprocessor.impl.poi.hssf.elements;
019:
020: import java.io.IOException;
021: import java.util.Hashtable;
022:
023: import org.apache.cocoon.components.elementprocessor.ElementProcessor;
024: import org.apache.cocoon.components.elementprocessor.types.Attribute;
025: import org.apache.cocoon.components.elementprocessor.types.BooleanConverter;
026: import org.apache.cocoon.components.elementprocessor.types.BooleanResult;
027: import org.apache.cocoon.components.elementprocessor.types.NumericConverter;
028: import org.apache.cocoon.components.elementprocessor.types.NumericResult;
029: import org.apache.cocoon.components.elementprocessor.types.Validator;
030:
031: import org.apache.poi.hssf.usermodel.HSSFCellStyle;
032: import org.apache.poi.hssf.usermodel.HSSFDataFormat;
033: import org.apache.poi.hssf.util.HSSFColor;
034:
035: /**
036: * No-op implementation of ElementProcessor to handle the "Style" tag
037: *
038: * This element is a container of other elements and has several
039: * attributes
040: *
041: * This element is not used in HSSFSerializer 1.0
042: *
043: * @author Marc Johnson (marc_johnson27591@hotmail.com)
044: * @author Andrew C. Oliver (acoliver2@users.sourceforge.net)
045: * @version CVS $Id: EPStyle.java 433543 2006-08-22 06:22:54Z crossley $
046: */
047: public class EPStyle extends BaseElementProcessor {
048: private static final String _general_format = "General";
049: private HorizontalAlignment _h_align;
050: private VerticalAlignment _v_align;
051: private BooleanResult _wrap_text;
052: private StyleOrientation _orient;
053: private NumericResult _shade;
054: private NumericResult _indent;
055: private ColorCode _fore;
056: private ColorCode _back;
057: private ColorCode _pattern_color;
058: private String _format;
059: private static final String _h_align_attribute = "HAlign";
060: private static final String _v_align_attribute = "VAlign";
061: private static final String _wrap_text_attribute = "WrapText";
062: private static final String _orient_attribute = "Orient";
063: private static final String _shade_attribute = "Shade";
064: private static final String _indent_attribute = "Indent";
065: private static final String _fore_attribute = "Fore";
066: private static final String _back_attribute = "Back";
067: private static final String _pattern_color_attribute = "PatternColor";
068: private static final String _format_attribute = "Format";
069:
070: private boolean invalid;
071:
072: private static final Validator _shade_validator = new Validator() {
073: public IOException validate(final Number number) {
074: return StyleShading.isValid(number.intValue()) ? null
075: : new IOException("\"" + number
076: + "\" is not a legal value");
077: }
078: };
079:
080: /**
081: * constructor
082: */
083: public EPStyle() {
084: super (null);
085: _h_align = null;
086: _v_align = null;
087: _wrap_text = null;
088: _orient = null;
089: _shade = null;
090: _indent = null;
091: _fore = null;
092: _back = null;
093: _pattern_color = null;
094: _format = null;
095: }
096:
097: /**
098: * Override of Initialize() implementation
099: * @param attributes the array of Attribute instances; may be empty, will
100: * never be null
101: * @param parent the parent ElementProcessor; may be null
102: * @exception IOException if anything is wrong
103: */
104: public void initialize(final Attribute[] attributes,
105: final ElementProcessor parent) throws IOException {
106: super .initialize(attributes, parent);
107:
108: EPStyleRegion sregion = (EPStyleRegion) parent;
109:
110: if (sregion.isValid()) {
111: Hashtable colorhash = sregion.getColorHash();
112:
113: HSSFCellStyle style = sregion.getStyle();
114: short cnvhalign = convertAlignment(getHorizontalAlignment()
115: .getCode());
116: style.setAlignment(cnvhalign);
117: short cnvvalign = convertVAlignment(getVerticalAlignment()
118: .getCode());
119: style.setVerticalAlignment(cnvvalign);
120: style.setFillPattern((short) getShade());
121:
122: Workbook workbook = getWorkbook();
123: HSSFDataFormat dataformat = workbook.createDataFormat();
124: if (getShade() == 1) {
125: // TODO: change to constant when upgrade to new HSSF
126: // solid w/foreground, bg doesn't matter
127: if (getLogger().isDebugEnabled()) {
128: getLogger().debug("shade = 1");
129: }
130: HSSFColor color = (HSSFColor) colorhash
131: .get(getBackgroundColor().toString());
132: if (color == null) {
133: if (getLogger().isDebugEnabled()) {
134: getLogger().debug(
135: "s1 BG couldn't find color for "
136: + getBackgroundColor()
137: .toString());
138: }
139: color = new HSSFColor.WHITE();
140: }
141: style.setFillForegroundColor(color.getIndex());
142: color = (HSSFColor) colorhash.get(getPatternColor()
143: .toString());
144: if (color == null) {
145: if (getLogger().isDebugEnabled()) {
146: getLogger().debug(
147: "s1 PC couldn't find color for "
148: + getPatternColor().toString());
149: }
150: color = new HSSFColor.BLACK();
151: }
152: style.setFillBackgroundColor(color.getIndex());
153: } else {
154: HSSFColor color = (HSSFColor) colorhash
155: .get(getBackgroundColor().toString());
156: if (color == null) {
157: if (getLogger().isDebugEnabled()) {
158: getLogger().debug(
159: "BG couldn't find color for "
160: + getBackgroundColor()
161: .toString());
162: }
163: color = new HSSFColor.BLACK();
164: }
165: style.setFillBackgroundColor(color.getIndex());
166: color = (HSSFColor) colorhash.get(getPatternColor()
167: .toString());
168: if (color == null) {
169: if (getLogger().isDebugEnabled()) {
170: getLogger().debug(
171: "PC couldn't find color for "
172: + getPatternColor().toString());
173: }
174: color = new HSSFColor.WHITE();
175: }
176: style.setFillForegroundColor(color.getIndex());
177: }
178: style.setWrapText(getWrapText());
179: style.setLocked(true);
180:
181: String format = null;
182: try {
183: format = getFormat();
184: } catch (NullPointerException e) {
185: format = _general_format;
186: }
187:
188: if (!_general_format.equals(format)) {
189: short valuenumber;
190: format = kludgeForGnumericMisformats(format);
191: format = kludgeForGnumericDateDivergence(format);
192: if (getLogger().isDebugEnabled()) {
193: getLogger().debug("setting format to " + format);
194: }
195: Object o = workbook.getValidate(format, dataformat
196: .getFormat(format));
197: Short sh = null;
198: sh = (Short) o;
199: valuenumber = sh.shortValue();
200: style.setDataFormat(valuenumber);
201: }
202: } else {
203: invalid = true;
204: }
205: }
206:
207: /**
208: * @return true if horizontal alignment general bit is set
209: * @exception IOException
210: */
211: public boolean isHorizontalGeneral() throws IOException {
212: return getHorizontalAlignment().isGeneral();
213: }
214:
215: /**
216: * @return true if horizontal alignment left bit is set
217: * @exception IOException
218: */
219: public boolean isHorizontalLeft() throws IOException {
220: return getHorizontalAlignment().isLeft();
221: }
222:
223: /**
224: * @return true if horizontal alignment right bit is set
225: * @exception IOException
226: */
227: public boolean isHorizontalRight() throws IOException {
228: return getHorizontalAlignment().isRight();
229: }
230:
231: /**
232: * @return true if horizontal alignment center bit is set
233: * @exception IOException
234: */
235: public boolean isHorizontalCenter() throws IOException {
236: return getHorizontalAlignment().isCenter();
237: }
238:
239: /**
240: * @return true if horizontal alignment fill bit is set
241: * @exception IOException
242: */
243: public boolean isHorizontalFill() throws IOException {
244: return getHorizontalAlignment().isFill();
245: }
246:
247: /**
248: * @return true if horizontal alignment justify bit is set
249: * @exception IOException
250: */
251: public boolean isHorizontalJustify() throws IOException {
252: return getHorizontalAlignment().isJustify();
253: }
254:
255: /**
256: * @return true if horizontal alignment center across selection bit is set
257: * @exception IOException
258: */
259: public boolean isHorizontalCenterAcrossSelection()
260: throws IOException {
261: return getHorizontalAlignment().isCenterAcrossSelection();
262: }
263:
264: /**
265: * @return true if vertical alignment top bit is set
266: * @exception IOException
267: */
268: public boolean isVerticalTop() throws IOException {
269: return getVerticalAlignment().isTop();
270: }
271:
272: /**
273: * @return true if vertical alignment bottom bit is set
274: * @exception IOException
275: */
276: public boolean isVerticalBottom() throws IOException {
277: return getVerticalAlignment().isBottom();
278: }
279:
280: /**
281: * @return true if vertical alignment center bit is set
282: * @exception IOException
283: */
284: public boolean isVerticalCenter() throws IOException {
285: return getVerticalAlignment().isCenter();
286: }
287:
288: /**
289: * @return true if vertical alignment justify bit is set
290: * @exception IOException
291: */
292: public boolean isVerticalJustify() throws IOException {
293: return getVerticalAlignment().isJustify();
294: }
295:
296: /**
297: * @return true if wrap text is enabled
298: * @exception IOException
299: */
300: public boolean getWrapText() throws IOException {
301: if (_wrap_text == null) {
302: _wrap_text = BooleanConverter
303: .extractBoolean(getValue(_wrap_text_attribute));
304: }
305: return _wrap_text.booleanValue();
306: }
307:
308: /**
309: * @return true if style orientation horiz bit is set
310: * @exception IOException
311: */
312: public boolean isStyleOrientationHoriz() throws IOException {
313: return getStyleOrientation().isHoriz();
314: }
315:
316: /**
317: * @return true if style orientation vert horiz text bit is set
318: * @exception IOException
319: */
320: public boolean isStyleOrientationVertHorizText() throws IOException {
321: return getStyleOrientation().isVertHorizText();
322: }
323:
324: /**
325: * @return true if style orientation vert vert text bit is set
326: * @exception IOException
327: */
328: public boolean isStyleOrientationVertVertText() throws IOException {
329: return getStyleOrientation().isVertVertText();
330: }
331:
332: /**
333: * @return true if style orientation vert vert text2 bit is set
334: * @exception IOException
335: */
336: public boolean isStyleOrientationVertVertText2() throws IOException {
337: return getStyleOrientation().isVertVertText2();
338: }
339:
340: /**
341: * @return shade as one of the public variables in StyleShading
342: * @exception IOException
343: */
344: public int getShade() throws IOException {
345: if (_shade == null) {
346: _shade = NumericConverter.extractInteger(
347: getValue(_shade_attribute), _shade_validator);
348: }
349: return _shade.intValue();
350: }
351:
352: /**
353: * @return indent
354: * @exception IOException
355: */
356: public int getIndent() throws IOException {
357: if (_indent == null) {
358: _indent = NumericConverter
359: .extractInteger(getValue(_indent_attribute));
360: }
361: return _indent.intValue();
362: }
363:
364: /**
365: * @return foreground color
366: * @exception IOException
367: */
368: public ColorCode getForegroundColor() throws IOException {
369: if (_fore == null) {
370: _fore = new ColorCode(getValue(_fore_attribute));
371: }
372: return _fore;
373: }
374:
375: /**
376: * @return background color
377: * @exception IOException
378: */
379: public ColorCode getBackgroundColor() throws IOException {
380: if (_back == null) {
381: _back = new ColorCode(getValue(_back_attribute));
382: }
383: return _back;
384: }
385:
386: /**
387: * @return pattern color
388: * @exception IOException
389: */
390: public ColorCode getPatternColor() throws IOException {
391: if (_pattern_color == null) {
392: _pattern_color = new ColorCode(
393: getValue(_pattern_color_attribute));
394: }
395: return _pattern_color;
396: }
397:
398: /**
399: * @return format string
400: * @exception IOException
401: */
402: public String getFormat() throws IOException {
403: if (_format == null) {
404: _format = getValue(_format_attribute);
405: /*
406: * if (_format == null) { throw new IOException("missing " +
407: * _format_attribute + " attribute");
408: */
409: }
410: return _format;
411: }
412:
413: private HorizontalAlignment getHorizontalAlignment()
414: throws IOException {
415: if (_h_align == null) {
416: _h_align = new HorizontalAlignment(
417: getValue(_h_align_attribute));
418: }
419: return _h_align;
420: }
421:
422: private VerticalAlignment getVerticalAlignment() throws IOException {
423: if (_v_align == null) {
424: _v_align = new VerticalAlignment(
425: getValue(_v_align_attribute));
426: }
427: return _v_align;
428: }
429:
430: private StyleOrientation getStyleOrientation() throws IOException {
431: if (_orient == null) {
432: _orient = new StyleOrientation(getValue(_orient_attribute));
433: }
434: return _orient;
435: }
436:
437: /**
438: * @return instance created in the EPStyles instance from
439: * HSSFColor.getTripletHash();
440: * @see org.apache.poi.hssf.util.HSSFColor#getTripletHash()
441: */
442: Hashtable getColorHash() {
443: return ((EPStyleRegion) getAncestor(EPStyleRegion.class))
444: .getColorHash();
445: }
446:
447: /**
448: * @return the HSSFCellStyle object associated with this style region.
449: */
450: HSSFCellStyle getStyle() {
451: return ((EPStyleRegion) getAncestor(EPStyleRegion.class))
452: .getStyle();
453: }
454:
455: /**
456: * @return validity (used to determine whether this is a big wasteful
457: * region with no purpose (gnumeric does this)
458: */
459: public boolean isValid() {
460: return (!invalid);
461: }
462:
463: /**
464: * deal with mismatch between gnumeric align and Excel
465: */
466: private short convertAlignment(short alignment) {
467: short retval = HSSFCellStyle.ALIGN_GENERAL; // its 0
468:
469: switch (alignment) {
470: case 1:
471: retval = HSSFCellStyle.ALIGN_GENERAL;
472: break;
473: case 2:
474: retval = HSSFCellStyle.ALIGN_LEFT;
475: break;
476: case 4:
477: retval = HSSFCellStyle.ALIGN_RIGHT;
478: break;
479: case 8:
480: retval = HSSFCellStyle.ALIGN_CENTER;
481: break;
482: case 16:
483: retval = HSSFCellStyle.ALIGN_FILL;
484: break;
485: case 32:
486: retval = HSSFCellStyle.ALIGN_JUSTIFY;
487: break;
488: case 64:
489: retval = HSSFCellStyle.ALIGN_CENTER_SELECTION;
490: break;
491: default:
492: retval = HSSFCellStyle.ALIGN_GENERAL;
493: }
494: return retval;
495: }
496:
497: /**
498: * deal with mismatch between gnumeric valign and Excel
499: */
500: private short convertVAlignment(short alignment) {
501: short retval = HSSFCellStyle.VERTICAL_TOP; // its 0
502:
503: switch (alignment) {
504: case 1:
505: retval = HSSFCellStyle.VERTICAL_TOP;
506: break;
507: case 2:
508: retval = HSSFCellStyle.VERTICAL_BOTTOM;
509: break;
510: case 4:
511: retval = HSSFCellStyle.VERTICAL_CENTER;
512: break;
513: case 8:
514: retval = HSSFCellStyle.VERTICAL_JUSTIFY;
515: break;
516: default:
517: retval = HSSFCellStyle.VERTICAL_TOP;
518: }
519: return retval;
520: }
521:
522: /**
523: * Takes in a Gnumeric format string and applies some rules to it. Some
524: * versions of Gnumeric seem to leave off the first parenthesis which
525: * causes them not to match the Excel-style format string. (which of course
526: * makes it a little hard to match)
527: */
528: private String kludgeForGnumericMisformats(String format) {
529: String retval = format;
530: if (getLogger().isDebugEnabled()) {
531: getLogger().debug(
532: "going out of the format kludger " + retval);
533: getLogger().debug("first )=" + format.indexOf(')'));
534: getLogger().debug("first (=" + format.indexOf('('));
535: }
536: if (format.indexOf(')') < format.indexOf('(')
537: && (format.indexOf(')') != -1)) {
538: retval = "(" + format;
539: }
540: if (getLogger().isDebugEnabled()) {
541: getLogger().debug(
542: "going out of the format kludger " + retval);
543: }
544: return retval;
545: }
546:
547: private String kludgeForGnumericDateDivergence(String format) {
548: String retval = format;
549: if (getLogger().isDebugEnabled()) {
550: getLogger().debug(
551: "going into the format kludgeForGnumericDateDivergence"
552: + retval);
553: }
554:
555: if (retval.equals("mm/dd/yy")) {
556: retval = "m/d/yy";
557: } else if (retval.equals("dd-mmm-yy")) {
558: retval = "d-mmm-yy";
559: } else if (retval.equals("dd-mmm")) {
560: retval = "d-mmm";
561: }
562: if (getLogger().isDebugEnabled()) {
563: getLogger().debug(
564: "going out of the format kludgeForGnumericDateDivergence"
565: + retval);
566: }
567: return retval;
568: }
569:
570: } // end public class EPStyle
|