1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-06-03 09:00:48 +00:00
plantuml/src/net/sourceforge/plantuml/UmlDiagram.java

305 lines
8.9 KiB
Java
Raw Normal View History

2010-11-15 20:35:36 +00:00
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009, Arnaud Roques
*
* Project Info: http://plantuml.sourceforge.net
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* Original Author: Arnaud Roques
*
2011-04-19 16:50:40 +00:00
* Revision $Revision: 6382 $
2010-11-15 20:35:36 +00:00
*
*/
package net.sourceforge.plantuml;
2011-04-19 16:50:40 +00:00
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Hashtable;
2010-11-15 20:35:36 +00:00
import java.util.List;
2011-04-19 16:50:40 +00:00
import net.sourceforge.plantuml.code.Compression;
import net.sourceforge.plantuml.code.CompressionZlib;
2010-11-15 20:35:36 +00:00
import net.sourceforge.plantuml.graphic.HorizontalAlignement;
2011-04-19 16:50:40 +00:00
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
2010-11-15 20:35:36 +00:00
public abstract class UmlDiagram extends AbstractPSystem implements PSystem {
private boolean rotation;
2011-02-14 11:56:34 +00:00
private boolean hideUnlinkedData;
2010-11-15 20:35:36 +00:00
private int minwidth = Integer.MAX_VALUE;
private List<String> title;
private List<String> header;
private List<String> footer;
private HorizontalAlignement headerAlignement = HorizontalAlignement.RIGHT;
private HorizontalAlignement footerAlignement = HorizontalAlignement.CENTER;
private final Pragma pragma = new Pragma();
private Scale scale;
private final SkinParam skinParam = new SkinParam();
final public void setTitle(List<String> strings) {
this.title = strings;
}
final public List<String> getTitle() {
return title;
}
final public int getMinwidth() {
return minwidth;
}
final public void setMinwidth(int minwidth) {
this.minwidth = minwidth;
}
final public boolean isRotation() {
return rotation;
}
final public void setRotation(boolean rotation) {
this.rotation = rotation;
}
public final ISkinParam getSkinParam() {
return skinParam;
}
public void setParam(String key, String value) {
skinParam.setParam(key.toLowerCase(), value);
}
public final List<String> getHeader() {
return header;
}
public final void setHeader(List<String> header) {
this.header = header;
}
public final List<String> getFooter() {
return footer;
}
public final void setFooter(List<String> footer) {
this.footer = footer;
}
public final HorizontalAlignement getHeaderAlignement() {
return headerAlignement;
}
public final void setHeaderAlignement(HorizontalAlignement headerAlignement) {
this.headerAlignement = headerAlignement;
}
public final HorizontalAlignement getFooterAlignement() {
return footerAlignement;
}
public final void setFooterAlignement(HorizontalAlignement footerAlignement) {
this.footerAlignement = footerAlignement;
}
abstract public UmlDiagramType getUmlDiagramType();
public Pragma getPragma() {
return pragma;
}
final public void setScale(Scale scale) {
this.scale = scale;
}
2011-01-05 18:23:06 +00:00
2010-11-15 20:35:36 +00:00
final public Scale getScale() {
return scale;
}
2011-01-05 18:23:06 +00:00
public final double getDpiFactor(FileFormatOption fileFormatOption) {
if (getSkinParam().getDpi() == 96) {
return 1.0;
}
return getSkinParam().getDpi() / 96.0;
}
public final int getDpi(FileFormatOption fileFormatOption) {
return getSkinParam().getDpi();
}
2011-02-14 11:56:34 +00:00
public final boolean isHideUnlinkedData() {
return hideUnlinkedData;
}
public final void setHideUnlinkedData(boolean hideUnlinkedData) {
this.hideUnlinkedData = hideUnlinkedData;
}
2011-04-19 16:50:40 +00:00
final public void exportDiagram(OutputStream os, StringBuilder cmap, int index, FileFormatOption fileFormatOption)
throws IOException {
List<BufferedImage> flashcodes = null;
try {
if ("split".equalsIgnoreCase(getSkinParam().getValue("flashcode"))
&& fileFormatOption.getFileFormat() == FileFormat.PNG) {
final String s = getSource().getPlainString();
flashcodes = exportSplitCompress(s);
} else if ("compress".equalsIgnoreCase(getSkinParam().getValue("flashcode"))
&& fileFormatOption.getFileFormat() == FileFormat.PNG) {
final String s = getSource().getPlainString();
flashcodes = exportFlashcodeCompress(s);
} else if (getSkinParam().getValue("flashcode") != null
&& fileFormatOption.getFileFormat() == FileFormat.PNG) {
final String s = getSource().getPlainString();
flashcodes = exportFlashcodeSimple(s);
}
} catch (WriterException e) {
Log.error("Cannot generate flashcode");
e.printStackTrace();
flashcodes = null;
}
exportDiagramInternal(os, cmap, index, fileFormatOption, flashcodes);
}
protected abstract void exportDiagramInternal(OutputStream os, StringBuilder cmap, int index,
FileFormatOption fileFormatOption, List<BufferedImage> flashcodes) throws IOException;
final protected void exportCmap(File suggestedFile, final StringBuilder cmap) throws FileNotFoundException {
final File cmapFile = new File(changeName(suggestedFile.getAbsolutePath()));
PrintWriter pw = null;
try {
pw = new PrintWriter(cmapFile);
pw.print(cmap.toString());
pw.close();
} finally {
if (pw != null) {
pw.close();
}
}
}
static String changeName(String name) {
return name.replaceAll("(?i)\\.\\w{3}$", ".cmapx");
}
private List<BufferedImage> exportFlashcodeSimple(String s) throws IOException, WriterException {
final QRCodeWriter writer = new QRCodeWriter();
final int multiple = 1;
final Hashtable hints = new Hashtable();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
final BitMatrix bit = writer.encode(s, BarcodeFormat.QR_CODE, multiple);
final BufferedImage im = MatrixToImageWriter.toBufferedImage(bit);
return Arrays.asList(im);
}
private List<BufferedImage> exportFlashcodeCompress(String s) throws IOException, WriterException {
final QRCodeWriter writer = new QRCodeWriter();
final int multiple = 1;
final Hashtable hints = new Hashtable();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
final Compression comp = new CompressionZlib();
final byte data[] = comp.compress(s.getBytes("UTF-8"));
// Encoder.DEFAULT_BYTE_MODE_ENCODING
final BitMatrix bit = writer.encode(new String(data, "ISO-8859-1"), BarcodeFormat.QR_CODE, multiple);
final BufferedImage im = MatrixToImageWriter.toBufferedImage(bit);
return Arrays.asList(im);
}
private List<BufferedImage> exportSplitCompress(String s) throws IOException, WriterException {
final QRCodeWriter writer = new QRCodeWriter();
final int multiple = 1;
final Hashtable hints = new Hashtable();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
final Compression comp = new CompressionZlib();
final byte data[] = comp.compress(s.getBytes("UTF-8"));
final List<BufferedImage> result = new ArrayList<BufferedImage>();
final List<byte[]> blocs = new ArrayList<byte[]>();
for (int i = 0; i < 4; i++) {
blocs.add(getSplited(data, i, 4));
}
blocs.add(xor(blocs));
for (byte d[] : blocs) {
// Encoder.DEFAULT_BYTE_MODE_ENCODING
final BitMatrix bit = writer.encode(new String(d, "ISO-8859-1"), BarcodeFormat.QR_CODE, multiple);
result.add(MatrixToImageWriter.toBufferedImage(bit));
}
return Collections.unmodifiableList(result);
}
static byte[] xor(List<byte[]> blocs) {
final byte result[] = new byte[blocs.get(0).length];
for (int i = 0; i < result.length; i++) {
result[i] = xor(blocs, i);
}
return result;
}
static byte xor(List<byte[]> blocs, int nb) {
byte result = 0;
for (byte[] bloc : blocs) {
result = (byte) (result ^ bloc[nb]);
}
return result;
}
static byte[] getSplited(byte[] data, int n, int total) {
final int size = (data.length + total - 1) / total;
assert size * total >= data.length;
final byte result[] = new byte[size + 1];
result[0] = (byte) (1 << n);
for (int i = 0; (i < size) && (n * total + i < data.length); i++) {
result[i + 1] = data[n * total + i];
}
return result;
}
2010-11-15 20:35:36 +00:00
}