commit 042fad13531d0da463aa752fd314509472dc39d1 Author: Arnaud Roques Date: Mon Nov 15 21:35:36 2010 +0100 Import from version 5538 diff --git a/build.xml b/build.xml new file mode 100644 index 000000000..ba8da6d6c --- /dev/null +++ b/build.xml @@ -0,0 +1,58 @@ + + + + PlantUML Build File + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/net/sourceforge/plantuml/AbstractPSystem.java b/src/net/sourceforge/plantuml/AbstractPSystem.java new file mode 100644 index 000000000..0ebf56725 --- /dev/null +++ b/src/net/sourceforge/plantuml/AbstractPSystem.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5520 $ + * + */ +package net.sourceforge.plantuml; + +import java.util.Date; +import java.util.Properties; + +import net.sourceforge.plantuml.version.Version; + +public abstract class AbstractPSystem implements PSystem { + + private UmlSource source; + + private String getVersion() { + final StringBuilder toAppend = new StringBuilder(); + toAppend.append("PlantUML version "); + toAppend.append(Version.version()); + toAppend.append("(" + new Date(Version.compileTime()) + ")\n"); + final Properties p = System.getProperties(); + toAppend.append(p.getProperty("java.runtime.name")); + toAppend.append('\n'); + toAppend.append(p.getProperty("java.vm.name")); + toAppend.append('\n'); + toAppend.append(p.getProperty("java.runtime.version")); + toAppend.append('\n'); + toAppend.append(p.getProperty("os.name")); + + return toAppend.toString(); + } + + final public String getMetadata() { + if (source == null) { + return getVersion(); + } + return source.getPlainString() + "\n" + getVersion(); + } + + final public UmlSource getSource() { + return source; + } + + final public void setSource(UmlSource source) { + this.source = source; + } + + public int getNbImages() { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java new file mode 100644 index 000000000..ca24b20ba --- /dev/null +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4780 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class BlockUml { + + private final List data; + private PSystem system; + + private static final Pattern pattern1 = Pattern.compile("^@startuml\\s+\"?(.*?)\"?$"); + + BlockUml(String... strings) { + this(Arrays.asList(strings)); + } + + BlockUml(List strings) { + final String s0 = strings.get(0); + if (s0.startsWith("@startuml") == false) { + throw new IllegalArgumentException(); + } + this.data = new ArrayList(strings); + } + + public String getFilename() { + if (OptionFlags.getInstance().isWord()) { + return null; + } + final Matcher m = pattern1.matcher(data.get(0)); + final boolean ok = m.find(); + if (ok == false) { + return null; + } + return m.group(1); + } + + public PSystem getSystem() throws IOException, InterruptedException { + if (system==null) { + createSystem(); + } + return system; + } + + private void createSystem() throws IOException, InterruptedException { + system = new PSystemBuilder().createPSystem(data); + + } + +} diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java new file mode 100644 index 000000000..21c861641 --- /dev/null +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -0,0 +1,106 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4952 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.preproc.Defines; +import net.sourceforge.plantuml.preproc.Preprocessor; +import net.sourceforge.plantuml.preproc.ReadLineReader; +import net.sourceforge.plantuml.preproc.UncommentReadLine; + +final public class BlockUmlBuilder { + + private final List blocks = new ArrayList(); + + public BlockUmlBuilder(List config, Defines defines, Reader reader) throws IOException { + Preprocessor includer = null; + try { + includer = new Preprocessor(new UncommentReadLine(new ReadLineReader(reader)), defines); + init(includer, config); + } finally { + if (includer != null) { + includer.close(); + } + } + } + + private boolean isArobaseEnduml(final String s) { + return s.equals("@enduml") || s.startsWith("@enduml "); + } + + private boolean isIgnoredLine(final String s) { + // return s.length() == 0 || s.startsWith("#") || s.startsWith("'"); + return s.length() == 0 || s.startsWith("'"); + } + + private boolean isArobaseStartuml(final String s) { + return s.equals("@startuml") || s.startsWith("@startuml "); + } + + private void init(Preprocessor includer, List config) throws IOException { + String s = null; + List current = null; + while ((s = includer.readLine()) != null) { + if (isArobaseStartuml(s)) { + current = new ArrayList(); + } + if (current != null && isIgnoredLine(s) == false) { + current.add(s); + } + if (isArobaseEnduml(s) && current != null) { + current.addAll(1, config); + blocks.add(new BlockUml(current)); + current = null; + } + } + } + + public List getBlockUmls() { + return Collections.unmodifiableList(blocks); + } + + /* + * private List getStrings(Reader reader) throws IOException { + * final List result = new ArrayList(); Preprocessor + * includer = null; try { includer = new Preprocessor(reader, defines); + * String s = null; while ((s = includer.readLine()) != null) { + * result.add(s); } } finally { if (includer != null) { includer.close(); } } + * return Collections.unmodifiableList(result); } + */ +} diff --git a/src/net/sourceforge/plantuml/ColorParam.java b/src/net/sourceforge/plantuml/ColorParam.java new file mode 100644 index 000000000..c15a6b022 --- /dev/null +++ b/src/net/sourceforge/plantuml/ColorParam.java @@ -0,0 +1,117 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5218 $ + * + */ +package net.sourceforge.plantuml; + + +public enum ColorParam { + background, + + activityBackground, + activityBorder, + activityStart, + activityEnd, + activityBar, + activityArrow, + + actorBackground, + actorBorder, + usecaseBorder, + usecaseBackground, + usecaseArrow, + + objectBackground, + objectBorder, + objectArrow, + + classBackground, + classBorder, + stereotypeCBackground, + stereotypeABackground, + stereotypeIBackground, + stereotypeEBackground, + classArrow, + + packageBackground, + packageBorder, + + componentBackground, + componentBorder, + interfaceBackground, + interfaceBorder, + componentArrow, + + stateBackground, + stateBorder, + stateArrow, + + noteBackground(true), + noteBorder, + + sequenceActorBackground(true), + sequenceActorBorder, + sequenceGroupBackground(true), + sequenceDividerBackground(true), + sequenceLifeLineBackground(true), + sequenceLifeLineBorder, + sequenceParticipantBackground(true), + sequenceParticipantBorder, + sequenceArrow, + sequenceEngloberLine, + sequenceEngloberBackground(true), + + iconPrivate, + iconPrivateBackground, + iconPackage, + iconPackageBackground, + iconProtected, + iconProtectedBackground, + iconPublic, + iconPublicBackground; + + private final boolean isBackground; + + private ColorParam() { + this(false); + } + + private ColorParam(boolean isBackground) { + this.isBackground = isBackground; + } + + protected boolean isBackground() { + return isBackground; + } + + +} diff --git a/src/net/sourceforge/plantuml/Dimension2DDouble.java b/src/net/sourceforge/plantuml/Dimension2DDouble.java new file mode 100644 index 000000000..5535193b3 --- /dev/null +++ b/src/net/sourceforge/plantuml/Dimension2DDouble.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4959 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.geom.Dimension2D; + +public class Dimension2DDouble extends Dimension2D { + + final private double width; + final private double height; + + public Dimension2DDouble(double width, double height) { + this.width = width; + this.height = height; + } + + @Override + public String toString() { + return "[" + width + "," + height + "]"; + } + + @Override + public double getHeight() { + return height; + } + + @Override + public double getWidth() { + return width; + } + + @Override + public void setSize(double width, double height) { + throw new UnsupportedOperationException(); + } + + public static Dimension2D delta(Dimension2D dim, double delta) { + return delta(dim, delta, delta); + } + + public static Dimension2D delta(Dimension2D dim, double deltaWidth, double deltaHeight) { + return new Dimension2DDouble(dim.getWidth() + deltaWidth, dim.getHeight() + deltaHeight); + } + +} diff --git a/src/net/sourceforge/plantuml/DirWatcher.java b/src/net/sourceforge/plantuml/DirWatcher.java new file mode 100644 index 000000000..d45b4bfb7 --- /dev/null +++ b/src/net/sourceforge/plantuml/DirWatcher.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5229 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.preproc.Defines; + +public class DirWatcher { + + final private File dir; + final private Option option; + final private String pattern; + + final private Map modifieds = new HashMap(); + + public DirWatcher(File dir, Option option, String pattern) { + this.dir = dir; + this.option = option; + this.pattern = pattern; + } + + public List buildCreatedFiles() throws IOException, InterruptedException { + final List result = new ArrayList(); + process(dir, result); + Collections.sort(result); + return Collections.unmodifiableList(result); + } + + private void process(File dirToProcess, final List result) throws IOException, InterruptedException { + for (File f : dirToProcess.listFiles()) { + if (f.isFile() == false) { + continue; + } + if (fileToProcess(f.getName()) == false) { + continue; + } + final long modified = f.lastModified(); + final Long previousModified = modifieds.get(f); + + if (previousModified == null || previousModified.longValue() != modified) { + final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), + option.getConfig(), option.getCharset(), option.getFileFormat()); + for (GeneratedImage g : sourceFileReader.getGeneratedImages()) { + result.add(g); + } + modifieds.put(f, modified); + } + } + } + + private boolean fileToProcess(String name) { + return name.matches(pattern); + } + + public final File getDir() { + return dir; + } + + // public void setPattern(String pattern) { + // this.pattern = pattern; + // } +} diff --git a/src/net/sourceforge/plantuml/Direction.java b/src/net/sourceforge/plantuml/Direction.java new file mode 100644 index 000000000..67c829f5b --- /dev/null +++ b/src/net/sourceforge/plantuml/Direction.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml; + +public enum Direction { + RIGHT, LEFT, DOWN, UP; + + public Direction getInv() { + if (this == RIGHT) { + return LEFT; + } + if (this == LEFT) { + return RIGHT; + } + if (this == DOWN) { + return UP; + } + if (this == UP) { + return DOWN; + } + throw new IllegalStateException(); + } +} diff --git a/src/net/sourceforge/plantuml/EmptyImageBuilder.java b/src/net/sourceforge/plantuml/EmptyImageBuilder.java new file mode 100644 index 000000000..aac2a952f --- /dev/null +++ b/src/net/sourceforge/plantuml/EmptyImageBuilder.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +public class EmptyImageBuilder { + + private final BufferedImage im; + private final Graphics2D g2d; + + public EmptyImageBuilder(int width, int height, Color background) { + im = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + g2d = im.createGraphics(); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setColor(background); + g2d.fillRect(0, 0, width, height); + } + + public BufferedImage getBufferedImage() { + return im; + } + + public Graphics2D getGraphics2D() { + return g2d; + } + +} diff --git a/src/net/sourceforge/plantuml/ErrorUml.java b/src/net/sourceforge/plantuml/ErrorUml.java new file mode 100644 index 000000000..530106e96 --- /dev/null +++ b/src/net/sourceforge/plantuml/ErrorUml.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +class ErrorUml { + + private final String error; + private final int position; + private final ErrorUmlType type; + + ErrorUml(ErrorUmlType type, String error, int position) { + if (error == null || type == null || StringUtils.isEmpty(error)) { + throw new IllegalArgumentException(); + } + this.error = error; + this.type = type; + this.position = position; + } + + @Override + public boolean equals(Object obj) { + final ErrorUml this2 = (ErrorUml) obj; + return this.type == this2.type && this.position == this2.position + && this.error.equals(this2.error); + } + + @Override + public int hashCode() { + return error.hashCode() + type.hashCode() + position; + } + + @Override + public String toString() { + return type.toString() + " " + position + " " + error; + } + + public final String getError() { + return error; + } + + public final ErrorUmlType getType() { + return type; + } + + public int getPosition() { + return position; + } + +} diff --git a/src/net/sourceforge/plantuml/ErrorUmlType.java b/src/net/sourceforge/plantuml/ErrorUmlType.java new file mode 100644 index 000000000..11f09f759 --- /dev/null +++ b/src/net/sourceforge/plantuml/ErrorUmlType.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +enum ErrorUmlType { + SYNTAX_ERROR, EXECUTION_ERROR + +} diff --git a/src/net/sourceforge/plantuml/FileFormat.java b/src/net/sourceforge/plantuml/FileFormat.java new file mode 100644 index 000000000..7e6e02f4a --- /dev/null +++ b/src/net/sourceforge/plantuml/FileFormat.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5333 $ + * + */ +package net.sourceforge.plantuml; + +public enum FileFormat { + PNG, SVG, EPS, EPS_VIA_SVG, ATXT, UTXT; + + public String getFileSuffix() { + if (this == EPS_VIA_SVG) { + throw new UnsupportedOperationException("Not used anymore"); + // return EPS.getFileSuffix(); + } + return "." + name().toLowerCase(); + } +} diff --git a/src/net/sourceforge/plantuml/FileGroup.java b/src/net/sourceforge/plantuml/FileGroup.java new file mode 100644 index 000000000..4e211fb75 --- /dev/null +++ b/src/net/sourceforge/plantuml/FileGroup.java @@ -0,0 +1,174 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FileGroup { + + private final List result = new ArrayList(); + private final String pattern; + private final List excluded; + private final Option option; + + private final static Pattern predirPath = Pattern.compile("^([^*?]*[/\\\\])?(.*)$"); + + public FileGroup(String pattern, List excluded, Option option) { + this.pattern = pattern; + this.excluded = excluded; + this.option = option; + if (pattern.indexOf("*") == -1 && pattern.indexOf("?") == -1) { + initNoStar(); + } else if (pattern.indexOf("**") != -1) { + recurse(); + } else { + initWithSimpleStar(); + } + Collections.sort(result); + + } + + private void recurse() { + final Matcher m = predirPath.matcher(pattern); + final boolean ok = m.find(); + if (ok == false) { + throw new IllegalArgumentException(); + } + final File parent; + if (m.group(1) == null) { + parent = new File("."); + } else { + parent = new File(m.group(1)); + } + initWithDoubleStar(parent); + } + + private void initNoStar() { + final File f = new File(pattern); + if (f.isDirectory()) { + addSimpleDirectory(f); + } else if (f.isFile()) { + addResultFile(f); + } + } + + private void addResultFile(final File f) { + final String path = getNormalizedPath(f); + for (String x : excluded) { + if (path.matches(toRegexp(x))) { + return; + } + } + result.add(f); + } + + private void addSimpleDirectory(File dir) { + if (OptionFlags.getInstance().isWord()) { + addSimpleDirectory(dir, "(?i)^.*_extr\\d+\\.txt$"); + } else { + addSimpleDirectory(dir, option.getPattern()); + } + } + + private void addSimpleDirectory(File dir, String pattern) { + if (dir.isDirectory() == false) { + throw new IllegalArgumentException("dir=" + dir); + } + for (File f : dir.listFiles()) { + if (f.getName().matches(pattern)) { + addResultFile(f); + } + } + } + + private static String getNormalizedPath(File f) { + return f.getPath().replace('\\', '/'); + } + + private final static Pattern noStarInDirectory = Pattern.compile("^(?:([^*?]*)[/\\\\])?([^/\\\\]*)$"); + + private void initWithSimpleStar() { + assert pattern.indexOf("**") == -1; + final Matcher m = noStarInDirectory.matcher(pattern); + if (m.find()) { + File dir = new File("."); + if (m.group(1) != null) { + final String dirPart = m.group(1); + dir = new File(dirPart); + } + + final String filesPart = m.group(2); + addSimpleDirectory(dir, toRegexp(filesPart)); + } else { + recurse(); + } + + } + + private void initWithDoubleStar(File currentDir) { + for (File f : currentDir.listFiles()) { + if (f.isDirectory()) { + initWithDoubleStar(f); + } else if (f.isFile()) { + final String path = getNormalizedPath(f); + if (path.matches(toRegexp(pattern))) { + addResultFile(f); + } + + } + } + + } + + public List getFiles() { + return Collections.unmodifiableList(result); + } + + static String toRegexp(String pattern) { + pattern = pattern.replace("\\", "/"); + pattern = pattern.replace(".", "\\."); + pattern = pattern.replace("?", "[^/]"); + pattern = pattern.replace("/**/", "(/|/.{0,}/)"); + pattern = pattern.replace("**", ".{0,}"); + pattern = pattern.replace("*", "[^/]{0,}"); + pattern = "(?i)^(\\./)?" + pattern + "$"; + return pattern; + } + +} diff --git a/src/net/sourceforge/plantuml/FileSystem.java b/src/net/sourceforge/plantuml/FileSystem.java new file mode 100644 index 000000000..62e5757bd --- /dev/null +++ b/src/net/sourceforge/plantuml/FileSystem.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4929 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.io.IOException; + +public class FileSystem { + + private final static FileSystem singleton = new FileSystem(); + + private File currentDir; + + private FileSystem() { + reset(); + } + + public static FileSystem getInstance() { + return singleton; + } + + public void setCurrentDir(File dir) { + if (dir == null) { + throw new IllegalArgumentException(); + } + Log.info("Setting current dir: " + dir); + this.currentDir = dir; + } + + public File getCurrentDir() { + return this.currentDir; + } + + public File getFile(String nameOrPath) throws IOException { + return new File(currentDir.getAbsoluteFile(), nameOrPath).getCanonicalFile(); + } + + public void reset() { + setCurrentDir(new File(".")); + } + +} diff --git a/src/net/sourceforge/plantuml/FontParam.java b/src/net/sourceforge/plantuml/FontParam.java new file mode 100644 index 000000000..d267a8e4d --- /dev/null +++ b/src/net/sourceforge/plantuml/FontParam.java @@ -0,0 +1,105 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5218 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.Font; + +public enum FontParam { + + ACTIVITY(14, Font.PLAIN, "black", null), + ACTIVITY_ARROW(13, Font.PLAIN, "black", null), + CIRCLED_CHARACTER(17, Font.BOLD, "black", "Courier"), + OBJECT_ARROW(10, Font.PLAIN, "black", null), + OBJECT_ATTRIBUTE(10, Font.PLAIN, "black", null), + OBJECT(12, Font.PLAIN, "black", null), + OBJECT_STEREOTYPE(12, Font.ITALIC, "black", null), + CLASS_ARROW(10, Font.PLAIN, "black", null), + CLASS_ATTRIBUTE(10, Font.PLAIN, "black", null), + CLASS(12, Font.PLAIN, "black", null), + CLASS_STEREOTYPE(12, Font.ITALIC, "black", null), + COMPONENT(14, Font.PLAIN, "black", null), + COMPONENT_STEREOTYPE(14, Font.ITALIC, "black", null), + COMPONENT_ARROW(13, Font.PLAIN, "black", null), + NOTE(13, Font.PLAIN, "black", null), + PACKAGE(14, Font.PLAIN, "black", null), + SEQUENCE_ACTOR(13, Font.PLAIN, "black", null), + SEQUENCE_ARROW(13, Font.PLAIN, "black", null), + SEQUENCE_ENGLOBER(13, Font.BOLD, "black", null), + SEQUENCE_DIVIDER(13, Font.BOLD, "black", null), + SEQUENCE_GROUPING(11, Font.BOLD, "black", null), + SEQUENCE_GROUPING_HEADER(13, Font.BOLD, "black", null), + SEQUENCE_PARTICIPANT(13, Font.PLAIN, "black", null), + SEQUENCE_TITLE(13, Font.BOLD, "black", null), + STATE(14, Font.PLAIN, "black", null), + STATE_ARROW(13, Font.PLAIN, "black", null), + STATE_ATTRIBUTE(12, Font.PLAIN, "black", null), + TITLE(18, Font.PLAIN, "black", null), + FOOTER(10, Font.PLAIN, "#888888", null), + HEADER(10, Font.PLAIN, "#888888", null), + USECASE(14, Font.PLAIN, "black", null), + USECASE_STEREOTYPE(14, Font.ITALIC, "black", null), + USECASE_ACTOR(14, Font.PLAIN, "black", null), + USECASE_ACTOR_STEREOTYPE(14, Font.ITALIC, "black", null), + USECASE_ARROW(13, Font.PLAIN, "black", null); + + private final int defaultSize; + private final int fontStyle; + private final String defaultColor; + private final String defaultFamily; + + private FontParam(int defaultSize, int fontStyle, String defaultColor, String defaultFamily) { + this.defaultSize = defaultSize; + this.fontStyle = fontStyle; + this.defaultColor = defaultColor; + this.defaultFamily = defaultFamily; + } + + public final int getDefaultSize() { + return defaultSize; + } + + public final int getDefaultFontStyle() { + return fontStyle; + } + + public final String getDefaultColor() { + return defaultColor; + } + + public String getDefaultFamily() { + return defaultFamily; + } + + +} diff --git a/src/net/sourceforge/plantuml/GeneratedImage.java b/src/net/sourceforge/plantuml/GeneratedImage.java new file mode 100644 index 000000000..b7343ace2 --- /dev/null +++ b/src/net/sourceforge/plantuml/GeneratedImage.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; + +public class GeneratedImage implements Comparable { + + private final File pngFile; + private final String description; + + public GeneratedImage(File pngFile, String description) { + if (pngFile == null) { + throw new IllegalArgumentException(); + } + this.pngFile = pngFile; + this.description = description; + } + + public File getPngFile() { + return pngFile; + } + + public String getDescription() { + return description; + } + + @Override + public String toString() { + return pngFile.getAbsolutePath() + " " + description; + } + + public int compareTo(GeneratedImage this2) { + final int cmp = this.pngFile.compareTo(this2.pngFile); + if (cmp != 0) { + return cmp; + } + return this.description.compareTo(this2.description); + } + + @Override + public int hashCode() { + return pngFile.hashCode() + description.hashCode(); + } + + @Override + public boolean equals(Object obj) { + final GeneratedImage this2 = (GeneratedImage) obj; + return this2.pngFile.equals(this.pngFile) && this2.description.equals(this.description); + } + +} diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java new file mode 100644 index 000000000..05163be40 --- /dev/null +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.Font; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public interface ISkinParam { + + public HtmlColor getBackgroundColor(); + + public String getValue(String key); + + public HtmlColor getHtmlColor(ColorParam param); + + public int getFontSize(FontParam param); + + public String getFontFamily(FontParam param); + + public HtmlColor getFontHtmlColor(FontParam param); + + public int getFontStyle(FontParam param); + + public Font getFont(FontParam fontParam); + + public int getCircledCharacterRadius(); + + public boolean isClassCollapse(); + + public int classAttributeIconSize(); + + public boolean isMonochrome(); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/LanguageDescriptor.java b/src/net/sourceforge/plantuml/LanguageDescriptor.java new file mode 100644 index 000000000..c9e02dd91 --- /dev/null +++ b/src/net/sourceforge/plantuml/LanguageDescriptor.java @@ -0,0 +1,135 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.PrintStream; +import java.util.Collection; +import java.util.Set; +import java.util.TreeSet; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class LanguageDescriptor { + + private final Set type = new TreeSet(); + private final Set keyword = new TreeSet(); + private final Set preproc = new TreeSet(); + + public LanguageDescriptor() { + type.add("actor"); + type.add("participant"); + type.add("usecase"); + type.add("class"); + type.add("interface"); + type.add("abstract"); + type.add("enum"); + type.add("component"); + type.add("state"); + type.add("object"); + + keyword.add("@startuml"); + keyword.add("@enduml"); + keyword.add("as"); + keyword.add("autonumber"); + keyword.add("title"); + keyword.add("newpage"); + keyword.add("box"); + keyword.add("alt"); + keyword.add("else"); + keyword.add("opt"); + keyword.add("loop"); + keyword.add("par"); + keyword.add("break"); + keyword.add("critical"); + keyword.add("note"); + keyword.add("group"); + keyword.add("left"); + keyword.add("right"); + keyword.add("of"); + keyword.add("over"); + keyword.add("end"); + keyword.add("activate"); + keyword.add("deactivate"); + keyword.add("destroy"); + keyword.add("create"); + keyword.add("footbox"); + keyword.add("hide"); + keyword.add("show"); + keyword.add("skinparam"); + keyword.add("skin"); + keyword.add("top"); + keyword.add("bottom"); + keyword.add("top to bottom direction"); + keyword.add("package"); + keyword.add("namespace"); + keyword.add("page"); + keyword.add("up"); + keyword.add("down"); + keyword.add("if"); + keyword.add("else"); + keyword.add("endif"); + keyword.add("partition"); + keyword.add("footer"); + keyword.add("header"); + keyword.add("center"); + keyword.add("rotate"); + + + preproc.add("!include"); + preproc.add("!define"); + preproc.add("!undef"); + preproc.add("!ifdef"); + preproc.add("!endif"); + preproc.add("!ifndef"); + } + + public void print(PrintStream ps) { + print(ps, "type", type); + print(ps, "keyword", keyword); + print(ps, "preprocessor", preproc); + print(ps, "skinparameter", SkinParam.getPossibleValues()); + print(ps, "color", HtmlColor.names()); + ps.println(";EOF"); + } + + private static void print(PrintStream ps, String name, Collection data) { + ps.println(";"+name); + ps.println(";" + data.size()); + for (String k : data) { + ps.println(k); + } + ps.println(); + } + +} diff --git a/src/net/sourceforge/plantuml/Log.java b/src/net/sourceforge/plantuml/Log.java new file mode 100644 index 000000000..3396b32ad --- /dev/null +++ b/src/net/sourceforge/plantuml/Log.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +public abstract class Log { + + private static long start = System.currentTimeMillis(); + + public static void debug(String s) { + } + + public static void info(String s) { + if (OptionFlags.getInstance().isVerbose()) { + System.out.println(format(s)); + } + } + + public static void error(String s) { + System.err.println(s); + } + + private static String format(String s) { + final long delta = System.currentTimeMillis() - start; + final StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(delta / 1000L); + sb.append("."); + sb.append(String.format("%03d", delta % 1000L)); + sb.append(" - "); + final long total = (Runtime.getRuntime().totalMemory()) / 1024 / 1024; + final long free = (Runtime.getRuntime().freeMemory()) / 1024 / 1024; + sb.append(total); + sb.append(" Mo) "); + sb.append(free); + sb.append(" Mo - "); + sb.append(s); + return sb.toString(); + + } +} diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java new file mode 100644 index 000000000..ad2c2afdc --- /dev/null +++ b/src/net/sourceforge/plantuml/Option.java @@ -0,0 +1,264 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5343 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.preproc.Defines; + +public class Option { + + private final List excludes = new ArrayList(); + private final List config = new ArrayList(); + private final Map defines = new LinkedHashMap(); + private String charset; + private boolean computeurl = false; + private boolean decodeurl = false; + private boolean pipe = false; + private boolean syntax = false; + + private File outputDir = null; + private final List result = new ArrayList(); + + public Option() { + } + + private FileFormat fileFormat = FileFormat.PNG; + + public FileFormat getFileFormat() { + return fileFormat; + } + + public void setFileFormat(FileFormat fileFormat) { + this.fileFormat = fileFormat; + } + + public Option(String... arg) throws InterruptedException, IOException { + if (arg.length == 0) { + OptionFlags.getInstance().setGui(true); + } + for (int i = 0; i < arg.length; i++) { + String s = arg[i]; + if (s.equalsIgnoreCase("-tsvg") || s.equalsIgnoreCase("-svg")) { + setFileFormat(FileFormat.SVG); + } else if (s.equalsIgnoreCase("-teps") || s.equalsIgnoreCase("-eps")) { + setFileFormat(FileFormat.EPS); + } else if (s.equalsIgnoreCase("-ttxt") || s.equalsIgnoreCase("-txt")) { + setFileFormat(FileFormat.ATXT); + } else if (s.equalsIgnoreCase("-tutxt") || s.equalsIgnoreCase("-utxt")) { + setFileFormat(FileFormat.UTXT); + } else if (s.equalsIgnoreCase("-output") || s.equalsIgnoreCase("-o")) { + i++; + if (i == arg.length) { + continue; + } + outputDir = new File(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i])); + } else if (s.equalsIgnoreCase("-graphvizdot") || s.equalsIgnoreCase("-graphviz_dot")) { + i++; + if (i == arg.length) { + continue; + } + OptionFlags.getInstance().setDotExecutable( + StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i])); + } else if (s.equalsIgnoreCase("-charset")) { + i++; + if (i == arg.length) { + continue; + } + charset = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i]); + } else if (s.startsWith("-o") && s.length() > 3) { + s = s.substring(2); + outputDir = new File(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(s)); + } else if (s.equalsIgnoreCase("-recurse") || s.equalsIgnoreCase("-r")) { + // recurse = true; + } else if (s.equalsIgnoreCase("-exclude") || s.equalsIgnoreCase("-x")) { + i++; + if (i == arg.length) { + continue; + } + excludes.add(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i])); + } else if (s.equalsIgnoreCase("-config")) { + i++; + if (i == arg.length) { + continue; + } + initConfig(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg[i])); + } else if (s.equalsIgnoreCase("-computeurl") || s.equalsIgnoreCase("-encodeurl")) { + this.computeurl = true; + } else if (s.startsWith("-c")) { + s = s.substring(2); + config.add(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(s)); + } else if (s.startsWith("-x")) { + s = s.substring(2); + excludes.add(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(s)); + } else if (s.equalsIgnoreCase("-debugdot")) { + OptionFlags.getInstance().setDebugDot(true); + } else if (s.equalsIgnoreCase("-verbose") || s.equalsIgnoreCase("-v")) { + OptionFlags.getInstance().setVerbose(true); + } else if (s.equalsIgnoreCase("-pipe") || s.equalsIgnoreCase("-p")) { + pipe = true; + } else if (s.equalsIgnoreCase("-syntax")) { + syntax = true; + OptionFlags.getInstance().setQuiet(true); + } else if (s.equalsIgnoreCase("-keepfiles") || s.equalsIgnoreCase("-keepfile")) { + OptionFlags.getInstance().setKeepTmpFiles(true); + } else if (s.equalsIgnoreCase("-metadata")) { + OptionFlags.getInstance().setMetadata(true); + } else if (s.equalsIgnoreCase("-word")) { + OptionFlags.getInstance().setWord(true); + OptionFlags.getInstance().setQuiet(true); + } else if (s.equalsIgnoreCase("-forcegd")) { + OptionFlags.getInstance().setForceGd(true); + } else if (s.equalsIgnoreCase("-forcecairo")) { + OptionFlags.getInstance().setForceCairo(true); + } else if (s.equalsIgnoreCase("-quiet")) { + OptionFlags.getInstance().setQuiet(true); + } else if (s.equalsIgnoreCase("-decodeurl")) { + this.decodeurl = true; + } else if (s.equalsIgnoreCase("-version")) { + OptionPrint.printVersion(); + } else if (s.startsWith("-D")) { + manageDefine(s.substring(2)); + } else if (s.equalsIgnoreCase("-testdot")) { + OptionPrint.printTestDot(); + } else if (s.equalsIgnoreCase("-about") || s.equalsIgnoreCase("-author") || s.equalsIgnoreCase("-authors")) { + OptionPrint.printAbout(); + } else if (s.equalsIgnoreCase("-help") || s.equalsIgnoreCase("-h") || s.equalsIgnoreCase("-?")) { + OptionPrint.printHelp(); + } else if (s.equalsIgnoreCase("-language")) { + OptionPrint.printLanguage(); + } else if (s.equalsIgnoreCase("-gui")) { + OptionFlags.getInstance().setGui(true); + } else { + result.add(s); + } + } + } + + public void initConfig(String filename) throws IOException { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(filename)); + String s = null; + while ((s = br.readLine()) != null) { + config.add(s); + } + } finally { + if (br != null) { + br.close(); + } + } + } + + private void manageDefine(String s) { + final Pattern p = Pattern.compile("^(\\w+)(?:=(.*))?$"); + final Matcher m = p.matcher(s); + if (m.find()) { + define(m.group(1), m.group(2)); + } + } + + public final File getOutputDir() { + return outputDir; + } + + public final static String getPattern() { + return "(?i)^.*\\.(txt|tex|java|htm|html|c|h|cpp|apt)$"; + } + + public void setOutputDir(File f) { + outputDir = f; + } + + public final List getExcludes() { + return Collections.unmodifiableList(excludes); + } + + public Defines getDefaultDefines() { + final Defines result = new Defines(); + for (Map.Entry ent : defines.entrySet()) { + result.define(ent.getKey(), ent.getValue()); + + } + return result; + } + + public void define(String name, String value) { + defines.put(name, value); + } + + public List getConfig() { + return Collections.unmodifiableList(config); + } + + public final List getResult() { + return Collections.unmodifiableList(result); + } + + public final String getCharset() { + return charset; + } + + public void setCharset(String s) { + this.charset = s; + + } + + public final boolean isComputeurl() { + return computeurl; + } + + public final boolean isDecodeurl() { + return decodeurl; + } + + public final boolean isPipe() { + return pipe; + } + + public final boolean isSyntax() { + return syntax; + } + +} diff --git a/src/net/sourceforge/plantuml/OptionFlags.java b/src/net/sourceforge/plantuml/OptionFlags.java new file mode 100644 index 000000000..ec165f866 --- /dev/null +++ b/src/net/sourceforge/plantuml/OptionFlags.java @@ -0,0 +1,173 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5244 $ + * + */ +package net.sourceforge.plantuml; + +public class OptionFlags { + + void reset() { + keepTmpFiles = false; + verbose = false; + metadata = false; + word = false; + debugDot = false; + forceGd = false; + forceCairo = false; + quiet = false; + dotExecutable = null; + } + + public boolean useJavaInsteadOfDot() { + return false; + } + + private static final OptionFlags singleton = new OptionFlags(); + + private boolean keepTmpFiles = false; + private boolean verbose = false; + private boolean metadata = false; + private boolean word = false; + private boolean systemExit = true; +// private boolean pipe = false; + private boolean debugDot = false; + private boolean forceGd = false; + private boolean forceCairo = false; + private String dotExecutable = null; + private boolean gui = false; + private boolean quiet = false; +// +// public final boolean isPipe() { +// return pipe; +// } +// +// public final void setPipe(boolean pipe) { +// this.pipe = pipe; +// } + + private OptionFlags() { + reset(); + } + + public static OptionFlags getInstance() { + return singleton; + } + + public final boolean isKeepTmpFiles() { + return keepTmpFiles; + } + + public final void setKeepTmpFiles(boolean keepTmpFiles) { + this.keepTmpFiles = keepTmpFiles; + } + + public final boolean isVerbose() { + return verbose; + } + + public final void setVerbose(boolean verbose) { + this.verbose = verbose; + } + + public final boolean isMetadata() { + return metadata; + } + + public final void setMetadata(boolean metadata) { + this.metadata = metadata; + } + + public final boolean isWord() { + return word; + } + + public final void setWord(boolean word) { + this.word = word; + } + + public final boolean isSystemExit() { + return systemExit; + } + + public final void setSystemExit(boolean systemExit) { + this.systemExit = systemExit; + } + + public final boolean isDebugDot() { + return debugDot; + } + + public final void setDebugDot(boolean debugDot) { + this.debugDot = debugDot; + } + + public final String getDotExecutable() { + return dotExecutable; + } + + public final void setDotExecutable(String dotExecutable) { + this.dotExecutable = dotExecutable; + } + + public final boolean isGui() { + return gui; + } + + public final void setGui(boolean gui) { + this.gui = gui; + } + + public final boolean isForceGd() { + return forceGd; + } + + public final void setForceGd(boolean forceGd) { + this.forceGd = forceGd; + } + + public final boolean isForceCairo() { + return forceCairo; + } + + public final void setForceCairo(boolean forceCairo) { + this.forceCairo = forceCairo; + } + + public final boolean isQuiet() { + return quiet; + } + + public final void setQuiet(boolean quiet) { + this.quiet = quiet; + } + +} diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java new file mode 100644 index 000000000..00b4c66f0 --- /dev/null +++ b/src/net/sourceforge/plantuml/OptionPrint.java @@ -0,0 +1,170 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5211 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; +import net.sourceforge.plantuml.version.Version; + +public class OptionPrint { + + static public void printTestDot() throws InterruptedException { + for (String s : getTestDotStrings()) { + System.err.println(s); + } + exit(); + } + + static public List getTestDotStrings() { + final List result = new ArrayList(); + final String ent = GraphvizUtils.getenvGraphvizDot(); + if (ent == null) { + result.add("The environment variable GRAPHVIZ_DOT has not been set"); + } else { + result.add("The environment variable GRAPHVIZ_DOT has been set to " + ent); + } + final File dotExe = GraphvizUtils.getDotExe(); + result.add("Dot executable is " + dotExe); + + boolean ok = true; + if (dotExe == null) { + result.add("Error: No dot executable found"); + ok = false; + } else if (dotExe.exists() == false) { + result.add("Error: file does not exist"); + ok = false; + } else if (dotExe.isFile() == false) { + result.add("Error: not a valid file"); + ok = false; + } else if (dotExe.canRead() == false) { + result.add("Error: cannot be read"); + ok = false; + } + + if (ok) { + try { + final String version = GraphvizUtils.dotVersion(); + result.add("Dot version: " + version); + result.add("Installation seems OK"); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + result.add("Error: only sequence diagrams will be generated"); + } + + return Collections.unmodifiableList(result); + } + + static public void printHelp() throws InterruptedException { + + final String charset = Charset.defaultCharset().displayName(); + + System.err.println("Usage: java -jar plantuml.jar [options] -gui"); + System.err.println("\t(to execute the GUI)"); + System.err.println(" or java -jar plantuml.jar [options] [files/dirs]"); + System.err.println("\t(to process files or directories)"); + System.err.println(); + System.err.println("You can use the following wildcards in files/dirs:"); + System.err.println("\t*\tmeans any characters but '" + File.separator + "'"); + System.err.println("\t?\tone and only one character but '" + File.separator + "'"); + System.err.println("\t**\tmeans any characters (used to recurse through directories)"); + System.err.println(); + System.err.println("where options include:"); + System.err.println(" -gui\t\tTo run the graphical user interface"); + System.err.println(" -tsvg\t\tTo generate images using SVG format"); + System.err.println(" -o[utput] \"dir\"\tTo generate images in the specified directory"); + System.err.println(" -config \"file\"\tTo read the provided config file before each diagram"); + System.err.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")"); + System.err.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern"); + System.err.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images"); + System.err.println(" -version\t\tTo display information about PlantUML and Java versions"); + System.err.println(" -v[erbose]\t\tTo have log information"); + System.err.println(" -quiet\t\tTo NOT print error message into the console"); + System.err.println(" -forcegd\t\tTo force dot to use GD PNG library"); + System.err.println(" -forcecairo\t\tTo force dot to use Cairo PNG library"); + System.err.println(" -keepfiles\t\tTo NOT delete temporary files after process"); + System.err.println(" -h[elp]\t\tTo display this help message"); + System.err.println(" -testdot\t\tTo test the installation of graphviz"); + System.err.println(" -graphvizdot \"exe\"\tTo specify dot executable"); + System.err.println(" -p[ipe]\t\tTo use stdin for PlantUML source and stdout for PNG/SVG generation"); + System.err.println(" -computeurl\t\tTo compute the encoded URL of a PlantUML source file"); + System.err.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL"); + System.err.println(); + System.err.println("If needed, you can setup the environment variable GRAPHVIZ_DOT."); + exit(); + } + + static private void exit() throws InterruptedException { + if (OptionFlags.getInstance().isSystemExit()) { + System.exit(0); + } + throw new InterruptedException("exit"); + } + + public static void printVersion() throws InterruptedException { + System.err.println("PlantUML version " + Version.version() + " (" + new Date(Version.compileTime()) + ")"); + final Properties p = System.getProperties(); + System.err.println(p.getProperty("java.runtime.name")); + System.err.println(p.getProperty("java.vm.name")); + System.err.println(p.getProperty("java.runtime.version")); + System.err.println(p.getProperty("os.name")); + exit(); + } + + public static void printAbout() throws InterruptedException { + System.err.println("PlantUML version " + Version.version() + " (" + new Date(Version.compileTime()) + ")"); + System.err.println(); + System.err.println("Original idea: Arnaud Roques"); + System.err.println("Word Macro: Alain Bertucat & Matthieu Sabatier"); + System.err.println("Eclipse Plugin: Claude Durif & Anne Pecoil"); + System.err.println("Site design: Raphael Cotisson"); + System.err.println(); + System.err.println("http://plantuml.sourceforge.net"); + exit(); + } + + public static void printLanguage() throws InterruptedException { + new LanguageDescriptor().print(System.out); + exit(); + } + +} diff --git a/src/net/sourceforge/plantuml/PSystem.java b/src/net/sourceforge/plantuml/PSystem.java new file mode 100644 index 000000000..b54b1baec --- /dev/null +++ b/src/net/sourceforge/plantuml/PSystem.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5520 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +public interface PSystem { + + List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException; + + void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException; + + int getNbImages(); + + String getDescription(); + + String getMetadata(); + + UmlSource getSource(); + +} diff --git a/src/net/sourceforge/plantuml/PSystemBasicFactory.java b/src/net/sourceforge/plantuml/PSystemBasicFactory.java new file mode 100644 index 000000000..5795f02b7 --- /dev/null +++ b/src/net/sourceforge/plantuml/PSystemBasicFactory.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + */ +package net.sourceforge.plantuml; + +public interface PSystemBasicFactory extends PSystemFactory { + + boolean executeLine(String line); +} diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java new file mode 100644 index 000000000..612bbb10e --- /dev/null +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -0,0 +1,119 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5207 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram.ActivityDiagramFactory; +import net.sourceforge.plantuml.classdiagram.ClassDiagramFactory; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagramFactory; +import net.sourceforge.plantuml.compositediagram.CompositeDiagramFactory; +import net.sourceforge.plantuml.eggs.PSystemEggFactory; +import net.sourceforge.plantuml.eggs.PSystemLostFactory; +import net.sourceforge.plantuml.eggs.PSystemPathFactory; +import net.sourceforge.plantuml.eggs.PSystemRIPFactory; +import net.sourceforge.plantuml.objectdiagram.ObjectDiagramFactory; +import net.sourceforge.plantuml.oregon.PSystemOregonFactory; +import net.sourceforge.plantuml.printskin.PrintSkinFactory; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory; +import net.sourceforge.plantuml.statediagram.StateDiagramFactory; +import net.sourceforge.plantuml.sudoku.PSystemSudokuFactory; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagramFactory; +import net.sourceforge.plantuml.version.PSystemVersionFactory; + +public class PSystemBuilder { + + final public PSystem createPSystem(final List strings) throws IOException, InterruptedException { + + final List factories = new ArrayList(); + factories.add(new SequenceDiagramFactory()); + factories.add(new ClassDiagramFactory()); + factories.add(new ActivityDiagramFactory()); + factories.add(new UsecaseDiagramFactory()); + factories.add(new ComponentDiagramFactory()); + factories.add(new StateDiagramFactory()); + factories.add(new CompositeDiagramFactory()); + factories.add(new ObjectDiagramFactory()); + factories.add(new PrintSkinFactory()); + factories.add(new PSystemVersionFactory()); + factories.add(new PSystemSudokuFactory()); + factories.add(new PSystemEggFactory()); + factories.add(new PSystemRIPFactory()); + factories.add(new PSystemLostFactory()); + factories.add(new PSystemPathFactory()); + factories.add(new PSystemOregonFactory()); + + final List errors = new ArrayList(); + for (PSystemFactory systemFactory : factories) { + final PSystem sys = new PSystemSingleBuilder(strings, systemFactory).getPSystem(); + if (isOk(sys)) { + return sys; + } + errors.add((PSystemError) sys); + } + + final PSystemError err = merge(errors); + if (OptionFlags.getInstance().isQuiet() == false) { + err.print(System.err); + } + return err; + + } + + private PSystemError merge(Collection ps) { + UmlSource source = null; + final List errors = new ArrayList(); + for (PSystemError system : ps) { + if (system.getSource() != null && source == null) { + source = system.getSource(); + } + errors.addAll(system.getErrorsUml()); + } + if (source == null) { + throw new IllegalStateException(); + } + return new PSystemError(source, errors); + } + + private boolean isOk(PSystem ps) { + if (ps == null || ps instanceof PSystemError) { + return false; + } + return true; + } + +} diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java new file mode 100644 index 000000000..3c5d0bedb --- /dev/null +++ b/src/net/sourceforge/plantuml/PSystemError.java @@ -0,0 +1,191 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5507 $ + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.TreeSet; + +import net.sourceforge.plantuml.graphic.GraphicStrings; + +public class PSystemError extends AbstractPSystem { + + private final List errorsUml = new ArrayList(); + private final List htmlStrings = new ArrayList(); + private final List plainStrings = new ArrayList(); + private final int higherErrorPosition; + private final Collection errs; + + public PSystemError(UmlSource source, List errorUml) { + this.errorsUml.addAll(errorUml); + this.setSource(source); + + final Collection executions = getErrors(ErrorUmlType.EXECUTION_ERROR); + if (executions.size() > 0) { + higherErrorPosition = getHigherErrorPosition(ErrorUmlType.EXECUTION_ERROR); + errs = getErrorsAt(higherErrorPosition, ErrorUmlType.EXECUTION_ERROR); + appendSource(higherErrorPosition, errs); + } else { + higherErrorPosition = getHigherErrorPosition(ErrorUmlType.SYNTAX_ERROR); + errs = getErrorsAt(higherErrorPosition, ErrorUmlType.SYNTAX_ERROR); + if (errs.size() != 1) { + throw new UnsupportedOperationException(errs.toString()); + } + appendSource(higherErrorPosition, errs); + } + + } + + public PSystemError(UmlSource source, ErrorUml... errorUml) { + this(source, Arrays.asList(errorUml)); + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + getPngError().writeImage(os, getMetadata(), fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getPngError().writeImage(os, getMetadata(), fileFormat); + } + + public GraphicStrings getPngError() throws IOException { + return new GraphicStrings(htmlStrings); + } + + private void appendSource(int position, Collection errs) { + final int limit = 4; + int start; + final int skip = position - limit + 1; + if (skip <= 0) { + start = 0; + } else { + if (skip == 1) { + htmlStrings.add("... (skipping 1 line) ..."); + plainStrings.add("... (skipping 1 line) ..."); + } else { + htmlStrings.add("... (skipping " + skip + " lines) ..."); + plainStrings.add("... (skipping " + skip + " lines) ..."); + } + start = position - limit + 1; + } + for (int i = start; i < position; i++) { + htmlStrings.add(StringUtils.hideComparatorCharacters(getSource().getLine(i))); + plainStrings.add(getSource().getLine(i)); + } + final String errorLine = getSource().getLine(position); + htmlStrings.add("" + StringUtils.hideComparatorCharacters(errorLine) + ""); + plainStrings.add(StringUtils.hideComparatorCharacters(errorLine)); + final StringBuilder underscore = new StringBuilder(); + for (int i = 0; i < errorLine.length(); i++) { + underscore.append("^"); + } + plainStrings.add(underscore.toString()); + for (String er : errs) { + htmlStrings.add(" " + er); + plainStrings.add(" " + er); + } + } + + private Collection getErrors(ErrorUmlType type) { + final Collection result = new LinkedHashSet(); + for (ErrorUml error : errorsUml) { + if (error.getType() == type) { + result.add(error); + } + } + return result; + } + + private int getHigherErrorPosition(ErrorUmlType type) { + int max = Integer.MIN_VALUE; + for (ErrorUml error : getErrors(type)) { + if (error.getPosition() > max) { + max = error.getPosition(); + } + } + if (max == Integer.MIN_VALUE) { + throw new IllegalStateException(); + } + return max; + } + + private Collection getErrorsAt(int position, ErrorUmlType type) { + final Collection result = new TreeSet(); + for (ErrorUml error : getErrors(type)) { + if (error.getPosition() == position && StringUtils.isNotEmpty(error.getError())) { + result.add(error.getError()); + } + } + return result; + } + + public String getDescription() { + return "(Error)"; + } + + public final List getErrorsUml() { + return Collections.unmodifiableList(errorsUml); + } + + public void print(PrintStream ps) { + for (String s : plainStrings) { + ps.println(StringUtils.showComparatorCharacters(s)); + } + } + + public final int getHigherErrorPosition() { + return higherErrorPosition; + } + + public final Collection getErrs() { + return Collections.unmodifiableCollection(errs); + } +} diff --git a/src/net/sourceforge/plantuml/PSystemFactory.java b/src/net/sourceforge/plantuml/PSystemFactory.java new file mode 100644 index 000000000..d79aeef58 --- /dev/null +++ b/src/net/sourceforge/plantuml/PSystemFactory.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +public interface PSystemFactory { + + PSystem getSystem(); + + void reset(); + +} diff --git a/src/net/sourceforge/plantuml/PSystemSingleBuilder.java b/src/net/sourceforge/plantuml/PSystemSingleBuilder.java new file mode 100644 index 000000000..8b4e7c8fd --- /dev/null +++ b/src/net/sourceforge/plantuml/PSystemSingleBuilder.java @@ -0,0 +1,195 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4975 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.CommandControl; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.PSystemCommandFactory; +import net.sourceforge.plantuml.command.ProtectedCommand; + +final public class PSystemSingleBuilder { + + private final Iterator it; + private final UmlSource source; + + private int nb = 0; + private AbstractPSystem sys; + + private boolean hasNext() { + return it.hasNext(); + } + + private String next() { + nb++; + return it.next(); + } + + public PSystem getPSystem() { + return sys; + } + + public PSystemSingleBuilder(List strings, PSystemFactory systemFactory) throws IOException { + source = new UmlSource(strings); + it = strings.iterator(); + if (next().startsWith("@startuml") == false) { + throw new UnsupportedOperationException(); + } + + if (systemFactory instanceof PSystemCommandFactory) { + executeUmlCommand((PSystemCommandFactory) systemFactory); + } else if (systemFactory instanceof PSystemBasicFactory) { + executeUmlBasic((PSystemBasicFactory) systemFactory); + } + } + + private void executeUmlBasic(PSystemBasicFactory systemFactory) throws IOException { + systemFactory.reset(); + while (hasNext()) { + final String s = next(); + if (s.equals("@enduml")) { + if (source.getSize() == 2) { + sys = buildEmptyError(source); + } else { + sys = (AbstractPSystem) systemFactory.getSystem(); + } + if (sys == null) { + return; + } + sys.setSource(source); + return; + } + final boolean ok = systemFactory.executeLine(s); + if (ok == false) { + sys = new PSystemError(source, new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", nb - 1)); + return; + } + } + sys = (AbstractPSystem) systemFactory.getSystem(); + sys.setSource(source); + } + + private PSystemError buildEmptyError(UmlSource source) { + final PSystemError result = new PSystemError(source, new ErrorUml(ErrorUmlType.SYNTAX_ERROR, + "Empty description", 1)); + return result; + } + + private void executeUmlCommand(PSystemCommandFactory systemFactory) throws IOException { + systemFactory.reset(); + while (hasNext()) { + final String s = next(); + if (s.equals("@enduml")) { + if (source.getSize() == 2) { + sys = buildEmptyError(source); + } else { + sys = (AbstractPSystem) systemFactory.getSystem(); + } + if (sys == null) { + return; + } + sys.setSource(source); + return; + } + final CommandControl commandControl = systemFactory.isValid(Arrays.asList(s)); + if (commandControl == CommandControl.NOT_OK) { + sys = new PSystemError(source, new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", nb - 1)); + return; + } else if (commandControl == CommandControl.OK_PARTIAL) { + final boolean ok = manageMultiline(systemFactory, s); + if (ok == false) { + sys = new PSystemError(source, new ErrorUml(ErrorUmlType.EXECUTION_ERROR, "Syntax Error?", nb - 1)); + return; + } + } else if (commandControl == CommandControl.OK) { + final Command cmd = new ProtectedCommand(systemFactory.createCommand(Arrays.asList(s))); + final CommandExecutionResult result = cmd.execute(Arrays.asList(s)); + if (result.isOk() == false) { + sys = new PSystemError(source, new ErrorUml(ErrorUmlType.EXECUTION_ERROR, result.getError(), + nb - 1)); + return; + } + testDeprecated(Arrays.asList(s), cmd); + } else { + assert false; + } + } + sys = (AbstractPSystem) systemFactory.getSystem(); + sys.setSource(source); + } + + private void testDeprecated(final List lines, final Command cmd) { + if (cmd.isDeprecated(lines)) { + Log.error("The following syntax is deprecated :"); + for (String s : lines) { + Log.error(s); + } + final String msg = cmd.getHelpMessageForDeprecated(lines); + if (msg != null) { + Log.error("Use instead :"); + Log.error(msg); + } + } + } + + private boolean manageMultiline(PSystemCommandFactory systemFactory, final String init) throws IOException { + final List lines = new ArrayList(); + lines.add(init); + while (hasNext()) { + final String s = next(); + if (s.equals("@enduml")) { + return false; + } + lines.add(s); + final CommandControl commandControl = systemFactory.isValid(lines); + if (commandControl == CommandControl.NOT_OK) { + throw new IllegalStateException(); + } + if (commandControl == CommandControl.OK) { + final Command cmd = systemFactory.createCommand(lines); + testDeprecated(lines, cmd); + return cmd.execute(lines).isOk(); + } + } + return false; + + } + +} diff --git a/src/net/sourceforge/plantuml/Pragma.java b/src/net/sourceforge/plantuml/Pragma.java new file mode 100644 index 000000000..0eae22abf --- /dev/null +++ b/src/net/sourceforge/plantuml/Pragma.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +public class Pragma { + + private final Map values = new LinkedHashMap(); + + public void define(String name, String value) { + values.put(name, value); + if (name.equalsIgnoreCase("graphviz_dot")) { + OptionFlags.getInstance().setDotExecutable(value); + } + } + + public boolean isDefine(String name) { + return values.containsKey(name); + } + + public void undefine(String name) { + values.remove(name); + } + + public String getValue(String name) { + final String result = values.get(name); + if (result == null) { + throw new IllegalArgumentException(); + } + return result; + } + + protected Set> entrySet() { + return Collections.unmodifiableSet(values.entrySet()); + } +} diff --git a/src/net/sourceforge/plantuml/Run.java b/src/net/sourceforge/plantuml/Run.java new file mode 100644 index 000000000..f92df1476 --- /dev/null +++ b/src/net/sourceforge/plantuml/Run.java @@ -0,0 +1,178 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5391 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.GraphicsEnvironment; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.List; + +import javax.swing.UIManager; + +import net.sourceforge.plantuml.code.Transcoder; +import net.sourceforge.plantuml.png.MetadataTag; +import net.sourceforge.plantuml.preproc.Defines; +import net.sourceforge.plantuml.swing.MainWindow; + +public class Run { + + public static void main(String[] argsArray) throws IOException, InterruptedException { + final Option option = new Option(argsArray); + if (OptionFlags.getInstance().isVerbose()) { + Log.info("GraphicsEnvironment.isHeadless() " + GraphicsEnvironment.isHeadless()); + } + if (OptionFlags.getInstance().isGui()) { + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Exception e) { + } + new MainWindow(option); + } else if (option.isPipe() || option.isSyntax()) { + managePipe(option); + } else { + manageFiles(option); + } + } + + private static void managePipe(Option option) throws IOException { + final String charset = option.getCharset(); + final BufferedReader br; + if (charset == null) { + br = new BufferedReader(new InputStreamReader(System.in)); + } else { + br = new BufferedReader(new InputStreamReader(System.in, charset)); + } + managePipe(option, br, System.out); + } + + static void managePipe(Option option, final BufferedReader br, final PrintStream ps) throws IOException { + final StringBuilder sb = new StringBuilder(); + String s = null; + while ((s = br.readLine()) != null) { + sb.append(s); + sb.append("\n"); + } + String source = sb.toString(); + if (source.contains("@startuml") == false) { + source = "@startuml\n" + source + "\n@enduml"; + } + final SourceStringReader sourceStringReader = new SourceStringReader(new Defines(), source, option.getConfig()); + + if (option.isSyntax()) { + try { + final PSystem system = sourceStringReader.getBlocks().get(0).getSystem(); + if (system instanceof UmlDiagram) { + ps.println(((UmlDiagram) system).getUmlDiagramType().name()); + ps.println(system.getDescription()); + } else if (system instanceof PSystemError) { + ps.println("ERROR"); + final PSystemError sys = (PSystemError) system; + ps.println(sys.getHigherErrorPosition()); + for (String er : sys.getErrs()) { + ps.println(er); + } + } else { + ps.println("OTHER"); + ps.println(system.getDescription()); + } + } catch (InterruptedException e) { + Log.error("InterruptedException " + e); + } + } else if (option.isPipe()) { + final String result = sourceStringReader.generateImage(ps, 0, option.getFileFormat()); + } + } + + private static void manageFile(File f, Option option) throws IOException, InterruptedException { + if (OptionFlags.getInstance().isMetadata()) { + System.out.println("------------------------"); + System.out.println(f); + // new Metadata().readAndDisplayMetadata(f); + System.out.println(); + System.out.println(new MetadataTag(f, "plantuml").getData()); + System.out.println("------------------------"); + } else { + final SourceFileReader sourceFileReader = new SourceFileReader(option.getDefaultDefines(), f, option + .getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormat()); + if (option.isComputeurl()) { + final List urls = sourceFileReader.getEncodedUrl(); + for (String s : urls) { + System.out.println(s); + } + } else { + sourceFileReader.getGeneratedImages(); + + } + } + } + + private static void manageFiles(Option option) throws IOException, InterruptedException { + + File lockFile = null; + try { + if (OptionFlags.getInstance().isWord()) { + final File dir = new File(option.getResult().get(0)); + final File javaIsRunningFile = new File(dir, "javaisrunning.tmp"); + javaIsRunningFile.delete(); + lockFile = new File(dir, "javaumllock.tmp"); + } + processArgs(option); + } finally { + if (lockFile != null) { + lockFile.delete(); + } + } + + } + + private static void processArgs(Option option) throws IOException, InterruptedException { + for (String s : option.getResult()) { + if (option.isDecodeurl()) { + final Transcoder transcoder = new Transcoder(); + System.out.println("@startuml"); + System.out.println(transcoder.decode(s)); + System.out.println("@enduml"); + } else { + final FileGroup group = new FileGroup(s, option.getExcludes(), option); + for (File f : group.getFiles()) { + manageFile(f, option); + } + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/Scale.java b/src/net/sourceforge/plantuml/Scale.java new file mode 100644 index 000000000..292c5aafe --- /dev/null +++ b/src/net/sourceforge/plantuml/Scale.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5401 $ + * + */ +package net.sourceforge.plantuml; + +public interface Scale { + + public double getScale(double width, double height); +} diff --git a/src/net/sourceforge/plantuml/ScaleHeight.java b/src/net/sourceforge/plantuml/ScaleHeight.java new file mode 100644 index 000000000..28b0434d5 --- /dev/null +++ b/src/net/sourceforge/plantuml/ScaleHeight.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5401 $ + * + */ +package net.sourceforge.plantuml; + +public class ScaleHeight implements Scale { + + private final double maxHeight; + + public ScaleHeight(double maxHeight) { + this.maxHeight = maxHeight; + } + + public double getScale(double width, double height) { + return maxHeight / height; + } +} diff --git a/src/net/sourceforge/plantuml/ScaleSimple.java b/src/net/sourceforge/plantuml/ScaleSimple.java new file mode 100644 index 000000000..8854b81cf --- /dev/null +++ b/src/net/sourceforge/plantuml/ScaleSimple.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5401 $ + * + */ +package net.sourceforge.plantuml; + +public class ScaleSimple implements Scale { + + private final double scale; + + public ScaleSimple(double scale) { + this.scale = scale; + } + + public double getScale(double width, double height) { + return scale; + } +} diff --git a/src/net/sourceforge/plantuml/ScaleWidth.java b/src/net/sourceforge/plantuml/ScaleWidth.java new file mode 100644 index 000000000..57dbe92f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/ScaleWidth.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5401 $ + * + */ +package net.sourceforge.plantuml; + +public class ScaleWidth implements Scale { + + private final double maxWidth; + + public ScaleWidth(double maxWidth) { + this.maxWidth = maxWidth; + } + + public double getScale(double width, double height) { + return maxWidth / width; + } +} diff --git a/src/net/sourceforge/plantuml/ScaleWidthAndHeight.java b/src/net/sourceforge/plantuml/ScaleWidthAndHeight.java new file mode 100644 index 000000000..ad3b3ce3f --- /dev/null +++ b/src/net/sourceforge/plantuml/ScaleWidthAndHeight.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5401 $ + * + */ +package net.sourceforge.plantuml; + +public class ScaleWidthAndHeight implements Scale { + + private final double maxWidth; + private final double maxHeight; + + public ScaleWidthAndHeight(double maxWidth, double maxHeight) { + this.maxWidth = maxWidth; + this.maxHeight = maxHeight; + } + + public double getScale(double width, double height) { + final double scale1 = maxWidth / width; + final double scale2 = maxHeight / height; +// if (scale1 > 1 && scale2 > 1) { +// return 1; +// } + return Math.min(scale1, scale2); + } +} diff --git a/src/net/sourceforge/plantuml/SignatureUtils.java b/src/net/sourceforge/plantuml/SignatureUtils.java new file mode 100644 index 000000000..19985936c --- /dev/null +++ b/src/net/sourceforge/plantuml/SignatureUtils.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3883 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import net.sourceforge.plantuml.code.AsciiEncoder; + +public class SignatureUtils { + + public static String getSignature(String s) { + try { + final AsciiEncoder coder = new AsciiEncoder(); + final MessageDigest msgDigest = MessageDigest.getInstance("MD5"); + msgDigest.update(s.getBytes("UTF-8")); + final byte[] digest = msgDigest.digest(); + return coder.encode(digest); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + throw new IllegalStateException(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + throw new IllegalStateException(); + } + } + + public static String getSignatureWithoutImgSrc(String s) { + return getSignature(purge(s)); + } + + public static String purge(String s) { + final String regex = "(?i)\\"; + s = s.replaceAll(regex, ""); + final String regex2 = "(?i)image=\"(?:[^\"]+[/\\\\])?([^/\\\\\\d.]+)\\d*(\\.\\w+)\""; + s = s.replaceAll(regex2, "image=\"$1$2\""); + return s; + } +} diff --git a/src/net/sourceforge/plantuml/SingleLine.java b/src/net/sourceforge/plantuml/SingleLine.java new file mode 100644 index 000000000..1a9960282 --- /dev/null +++ b/src/net/sourceforge/plantuml/SingleLine.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3824 $ + * + */ +package net.sourceforge.plantuml; + +public interface SingleLine { + + PSystem getSystemFromSingleLine(String singleLine); +} diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java new file mode 100644 index 000000000..251523444 --- /dev/null +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -0,0 +1,196 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5403 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.Font; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class SkinParam implements ISkinParam { + + private final Map params = new HashMap(); + + public void setParam(String key, String value) { + params.put(key.toLowerCase().trim(), value.trim()); + } + + public HtmlColor getBackgroundColor() { + final HtmlColor result = getHtmlColor(ColorParam.background); + if (result == null) { + return new HtmlColor("white"); + } + return result; + } + + public String getValue(String key) { + return params.get(key.toLowerCase().replaceAll("_", "")); + } + + static String humanName(String key) { + final StringBuilder sb = new StringBuilder(); + boolean upper = true; + for (int i = 0; i < key.length(); i++) { + final char c = key.charAt(i); + if (c == '_') { + upper = true; + } else { + sb.append(upper ? Character.toUpperCase(c) : Character.toLowerCase(c)); + upper = false; + } + } + return sb.toString(); + } + + public HtmlColor getHtmlColor(ColorParam param) { + final String value = getValue(param.name() + "color"); + if (value == null || HtmlColor.isValid(value) == false) { + return null; + } + return new HtmlColor(value); + } + + public int getFontSize(FontParam param) { + String value = getValue(param.name() + "fontsize"); + if (value == null || value.matches("\\d+") == false) { + value = getValue("defaultfontsize"); + } + if (value == null || value.matches("\\d+") == false) { + return param.getDefaultSize(); + } + return Integer.parseInt(value); + } + + public String getFontFamily(FontParam param) { + // Times, Helvetica, Courier or Symbol + String value = getValue(param.name() + "fontname"); + if (value != null) { + return value; + } + if (param != FontParam.CIRCLED_CHARACTER) { + value = getValue("defaultfontname"); + if (value != null) { + return value; + } + } + return param.getDefaultFamily(); + } + + public HtmlColor getFontHtmlColor(FontParam param) { + String value = getValue(param.name() + "fontcolor"); + if (value == null) { + value = getValue("defaultfontcolor"); + } + if (value == null) { + value = param.getDefaultColor(); + } + return new HtmlColor(value); + } + + public int getFontStyle(FontParam param) { + String value = getValue(param.name() + "fontstyle"); + if (value == null) { + value = getValue("defaultfontstyle"); + } + if (value == null) { + return param.getDefaultFontStyle(); + } + int result = Font.PLAIN; + if (value.toLowerCase().contains("bold")) { + result = result | Font.BOLD; + } + if (value.toLowerCase().contains("italic")) { + result = result | Font.ITALIC; + } + return result; + } + + public Font getFont(FontParam fontParam) { + return new Font(getFontFamily(fontParam), getFontStyle(fontParam), getFontSize(fontParam)); + } + + public int getCircledCharacterRadius() { + final String value = getValue("circledcharacterradius"); + if (value != null && value.matches("\\d+")) { + return Integer.parseInt(value); + } + // return 11; + // System.err.println("SIZE1="+getFontSize(FontParam.CIRCLED_CHARACTER)); + // System.err.println("SIZE1="+getFontSize(FontParam.CIRCLED_CHARACTER)/3); + return getFontSize(FontParam.CIRCLED_CHARACTER) / 3 + 6; + } + + public boolean isClassCollapse() { + return true; + } + + public int classAttributeIconSize() { + final String value = getValue("classAttributeIconSize"); + if (value != null && value.matches("\\d+")) { + return Integer.parseInt(value); + } + return 10; + } + + public boolean isMonochrome() { + return "true".equals(getValue("monochrome")); + } + + public static Collection getPossibleValues() { + final Set result = new TreeSet(); + result.add("Monochrome"); + result.add("BackgroundColor"); + result.add("CircledCharacterRadius"); + result.add("ClassAttributeIconSize"); + result.add("DefaultFontName"); + result.add("DefaultFontStyle"); + result.add("DefaultFontSize"); + result.add("DefaultFontColor"); + for (FontParam p : EnumSet.allOf(FontParam.class)) { + final String h = humanName(p.name()); + result.add(h + "FontStyle"); + result.add(h + "FontName"); + result.add(h + "FontSize"); + result.add(h + "FontColor"); + } + return Collections.unmodifiableSet(result); + } + +} diff --git a/src/net/sourceforge/plantuml/SkinParamBackcolored.java b/src/net/sourceforge/plantuml/SkinParamBackcolored.java new file mode 100644 index 000000000..04de12f6c --- /dev/null +++ b/src/net/sourceforge/plantuml/SkinParamBackcolored.java @@ -0,0 +1,110 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4246 $ + * + */ +package net.sourceforge.plantuml; + +import java.awt.Font; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class SkinParamBackcolored implements ISkinParam { + + final private ISkinParam skinParam; + final private HtmlColor backColorElement; + final private HtmlColor backColorGeneral; + + public SkinParamBackcolored(ISkinParam skinParam, HtmlColor backColorElement) { + this(skinParam, backColorElement, null); + } + + public SkinParamBackcolored(ISkinParam skinParam, + HtmlColor backColorElement, HtmlColor backColorGeneral) { + this.skinParam = skinParam; + this.backColorElement = backColorElement; + this.backColorGeneral = backColorGeneral; + } + + public HtmlColor getBackgroundColor() { + if (backColorGeneral != null) { + return backColorGeneral; + } + return skinParam.getBackgroundColor(); + } + + public int getCircledCharacterRadius() { + return skinParam.getCircledCharacterRadius(); + } + + public Font getFont(FontParam fontParam) { + return skinParam.getFont(fontParam); + } + + public String getFontFamily(FontParam param) { + return skinParam.getFontFamily(param); + } + + public HtmlColor getFontHtmlColor(FontParam param) { + return skinParam.getFontHtmlColor(param); + } + + public int getFontSize(FontParam param) { + return skinParam.getFontSize(param); + } + + public int getFontStyle(FontParam param) { + return skinParam.getFontStyle(param); + } + + public HtmlColor getHtmlColor(ColorParam param) { + if (param.isBackground() && backColorElement != null) { + return backColorElement; + } + return skinParam.getHtmlColor(param); + } + + public String getValue(String key) { + return skinParam.getValue(key); + } + + public boolean isClassCollapse() { + return skinParam.isClassCollapse(); + } + + public int classAttributeIconSize() { + return skinParam.classAttributeIconSize(); + } + + public boolean isMonochrome() { + return skinParam.isMonochrome(); + } +} diff --git a/src/net/sourceforge/plantuml/SourceFileReader.java b/src/net/sourceforge/plantuml/SourceFileReader.java new file mode 100644 index 000000000..ba394f716 --- /dev/null +++ b/src/net/sourceforge/plantuml/SourceFileReader.java @@ -0,0 +1,151 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4771 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.code.Transcoder; +import net.sourceforge.plantuml.preproc.Defines; + +public class SourceFileReader { + + private final File file; + private final File outputDirectory; + + private final BlockUmlBuilder builder; + private FileFormat fileFormat; + + public SourceFileReader(File file) throws IOException { + this(file, file.getAbsoluteFile().getParentFile()); + } + + public SourceFileReader(final File file, File outputDirectory) throws IOException { + this(new Defines(), file, outputDirectory, Collections. emptyList(), null, FileFormat.PNG); + } + + public SourceFileReader(final File file, File outputDirectory, FileFormat fileFormat) throws IOException { + this(new Defines(), file, outputDirectory, Collections. emptyList(), null, fileFormat); + } + + public SourceFileReader(Defines defines, final File file, File outputDirectory, List config, + String charset, FileFormat fileFormat) throws IOException { + this.file = file; + this.fileFormat = fileFormat; + if (file.exists() == false) { + throw new IllegalArgumentException(); + } + FileSystem.getInstance().setCurrentDir(file.getAbsoluteFile().getParentFile()); + if (outputDirectory == null) { + outputDirectory = file.getAbsoluteFile().getParentFile(); + } else if (outputDirectory.isAbsolute() == false) { + outputDirectory = FileSystem.getInstance().getFile(outputDirectory.getName()); + } + if (outputDirectory.exists() == false) { + outputDirectory.mkdirs(); + } + this.outputDirectory = outputDirectory; + + builder = new BlockUmlBuilder(config, defines, getReader(charset)); + } + + public List getGeneratedImages() throws IOException, InterruptedException { + Log.info("Reading file: " + file); + + int cpt = 0; + final List result = new ArrayList(); + + for (BlockUml blockUml : builder.getBlockUmls()) { + String newName = blockUml.getFilename(); + + if (newName == null) { + newName = changeName(file.getName(), cpt++, fileFormat); + } + + final File suggested = new File(outputDirectory, newName); + suggested.getParentFile().mkdirs(); + + for (File f : blockUml.getSystem().createFiles(suggested, fileFormat)) { + final String desc = "[" + file.getName() + "] " + blockUml.getSystem().getDescription(); + final GeneratedImage generatedImage = new GeneratedImage(f, desc); + result.add(generatedImage); + } + + } + + Log.info("Number of image(s): " + result.size()); + + return Collections.unmodifiableList(result); + } + + public List getEncodedUrl() throws IOException, InterruptedException { + final List result = new ArrayList(); + final Transcoder transcoder = new Transcoder(); + for (BlockUml blockUml : builder.getBlockUmls()) { + final String source = blockUml.getSystem().getSource().getPlainString(); + final String encoded = transcoder.encode(source); + result.add(encoded); + } + return Collections.unmodifiableList(result); + } + + static String changeName(String name, int cpt, FileFormat fileFormat) { + if (cpt == 0) { + return name.replaceAll("\\.\\w+$", fileFormat.getFileSuffix()); + } + return name.replaceAll("\\.\\w+$", "_" + String.format("%03d", cpt) + fileFormat.getFileSuffix()); + } + + private Reader getReader(String charset) throws FileNotFoundException, UnsupportedEncodingException { + if (charset == null) { + Log.info("Using default charset"); + return new InputStreamReader(new FileInputStream(file)); + } + Log.info("Using charset " + charset); + return new InputStreamReader(new FileInputStream(file), charset); + } + + public final void setFileFormat(FileFormat fileFormat) { + this.fileFormat = fileFormat; + } + +} diff --git a/src/net/sourceforge/plantuml/SourceStringReader.java b/src/net/sourceforge/plantuml/SourceStringReader.java new file mode 100644 index 000000000..2256ed885 --- /dev/null +++ b/src/net/sourceforge/plantuml/SourceStringReader.java @@ -0,0 +1,103 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4041 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.graphic.GraphicStrings; +import net.sourceforge.plantuml.preproc.Defines; + +public class SourceStringReader { + + final private List blocks; + + public SourceStringReader(String source) { + this(new Defines(), source, Collections. emptyList()); + } + + public SourceStringReader(Defines defines, String source, List config) { + try { + final BlockUmlBuilder builder = new BlockUmlBuilder(config, defines, new StringReader(source)); + this.blocks = builder.getBlockUmls(); + } catch (IOException e) { + throw new IllegalStateException(); + } + } + + public String generateImage(OutputStream os) throws IOException { + return generateImage(os, 0); + } + + public String generateImage(OutputStream os, FileFormat fileFormat) throws IOException { + return generateImage(os, 0, fileFormat); + } + + public String generateImage(OutputStream os, int numImage) throws IOException { + return generateImage(os, numImage, FileFormat.PNG); + } + + public String generateImage(OutputStream os, int numImage, FileFormat fileFormat) throws IOException { + if (blocks.size() == 0) { + final GraphicStrings error = new GraphicStrings(Arrays.asList("No @startuml found")); + error.writeImage(os, fileFormat); + return null; + } + try { + for (BlockUml b : blocks) { + final PSystem system = b.getSystem(); + final int nbInSystem = system.getNbImages(); + if (numImage < nbInSystem) { + system.createFile(os, numImage, fileFormat); + return system.getDescription(); + } + numImage -= nbInSystem; + } + } catch (InterruptedException e) { + return null; + } + Log.error("numImage is too big = "); + return null; + + } + + public final List getBlocks() { + return Collections.unmodifiableList(blocks); + } + +} diff --git a/src/net/sourceforge/plantuml/SpecificBackcolorable.java b/src/net/sourceforge/plantuml/SpecificBackcolorable.java new file mode 100644 index 000000000..5c7e6ec50 --- /dev/null +++ b/src/net/sourceforge/plantuml/SpecificBackcolorable.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public interface SpecificBackcolorable { + + public HtmlColor getSpecificBackColor(); + + public void setSpecificBackcolor(String specificBackcolor); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/StringUtils.java b/src/net/sourceforge/plantuml/StringUtils.java new file mode 100644 index 000000000..f6355702f --- /dev/null +++ b/src/net/sourceforge/plantuml/StringUtils.java @@ -0,0 +1,263 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5427 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringUtils { + + static private final Pattern multiLines = Pattern.compile("((?:\\\\\\\\|[^\\\\])+)(\\\\n)?"); + + public static String getPlateformDependentAbsolutePath(File file) { + return file.getAbsolutePath(); + + } + + public static List getWithNewlines(String s) { + if (s == null) { + throw new IllegalArgumentException(); + } + final Matcher matcher = multiLines.matcher(s); + final List strings = new ArrayList(); + + while (matcher.find()) { + strings.add(matcher.group(1).replace("\\\\", "\\")); + } + return strings; + } + + public static String getMergedLines(List strings) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < strings.size(); i++) { + sb.append(strings.get(i)); + if (i < strings.size() - 1) { + sb.append("\\n"); + } + } + return sb.toString(); + } + + final static public List getSplit(Pattern pattern, String line) { + final Matcher m = pattern.matcher(line); + if (m.find() == false) { + return null; + } + final List result = new ArrayList(); + for (int i = 1; i <= m.groupCount(); i++) { + result.add(m.group(i)); + } + return result; + + } + + public static boolean isNotEmpty(String input) { + return input != null && input.trim().length() > 0; + } + + public static boolean isEmpty(String input) { + return input == null || input.trim().length() == 0; + } + + public static String manageHtml(String s) { + s = s.replace("<", "<"); + s = s.replace(">", ">"); + return s; + } + + public static String manageArrowForSequence(String s) { + s = s.replace('=', '-'); + return s; + } + + public static String manageArrowForCuca(String s) { + final Direction dir = getArrowDirection(s); + s = s.replace('=', '-'); + s = s.replaceAll("\\w*", ""); + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + s = s.replaceAll("-+", "-"); + } + if (s.length() == 2 && (dir == Direction.UP || dir == Direction.DOWN)) { + s = s.replaceFirst("-", "--"); + } + return s; + } + + public static String manageQueueForCuca(String s) { + final Direction dir = getQueueDirection(s); + s = s.replace('=', '-'); + s = s.replaceAll("\\w*", ""); + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + s = s.replaceAll("-+", "-"); + } + if (s.length() == 1 && (dir == Direction.UP || dir == Direction.DOWN)) { + s = s.replaceFirst("-", "--"); + } + return s; + } + + public static Direction getArrowDirection(String s) { + if (s.endsWith(">")) { + return getQueueDirection(s.substring(0, s.length() - 1)); + } + if (s.startsWith("<")) { + if (s.length() == 2) { + return Direction.LEFT; + } + return Direction.UP; + } + throw new IllegalArgumentException(s); + } + + public static Direction getQueueDirection(String s) { + if (s.indexOf('<') != -1 || s.indexOf('>') != -1) { + throw new IllegalArgumentException(s); + } + s = s.toLowerCase(); + if (s.contains("left")) { + return Direction.LEFT; + } + if (s.contains("right")) { + return Direction.RIGHT; + } + if (s.contains("up")) { + return Direction.UP; + } + if (s.contains("down")) { + return Direction.DOWN; + } + if (s.contains("l")) { + return Direction.LEFT; + } + if (s.contains("r")) { + return Direction.RIGHT; + } + if (s.contains("u")) { + return Direction.UP; + } + if (s.contains("d")) { + return Direction.DOWN; + } + if (s.length() == 1) { + return Direction.RIGHT; + } + return Direction.DOWN; + } + + public static String eventuallyRemoveStartingAndEndingDoubleQuote(String s) { + if (s.startsWith("\"") && s.endsWith("\"")) { + return s.substring(1, s.length() - 1); + } + if (s.startsWith("(") && s.endsWith(")")) { + return s.substring(1, s.length() - 1); + } + if (s.startsWith("[") && s.endsWith("]")) { + return s.substring(1, s.length() - 1); + } + if (s.startsWith(":") && s.endsWith(":")) { + return s.substring(1, s.length() - 1); + } + return s; + } + + // private static String cleanLineFromSource(String s) { + // if (s.startsWith("\uFEFF")) { + // s = s.substring(1); + // } + // if (s.startsWith("~~")) { + // s = s.substring("~~".length()); + // } + // // if (s.startsWith(" * ")) { + // // s = s.substring(" * ".length()); + // // } + // s = s.replaceFirst("^\\s+\\* ", ""); + // if (s.equals(" *")) { + // s = ""; + // } + // s = s.trim(); + // while (s.startsWith(" ") || s.startsWith("/") || s.startsWith("\t") || + // s.startsWith("%") || s.startsWith("/*")) { + // if (s.startsWith("/*")) { + // s = s.substring(2).trim(); + // } else { + // s = s.substring(1).trim(); + // } + // } + // return s; + // } + + public static boolean isCJK(char c) { + final Character.UnicodeBlock block = Character.UnicodeBlock.of(c); + System.err.println(block); + return false; + } + + public static char hiddenLesserThan() { + return '\u0005'; + } + + public static char hiddenBiggerThan() { + return '\u0006'; + } + + public static String hideComparatorCharacters(String s) { + s = s.replace('<', hiddenLesserThan()); + s = s.replace('>', hiddenBiggerThan()); + return s; + } + + public static String showComparatorCharacters(String s) { + s = s.replace(hiddenLesserThan(), '<'); + s = s.replace(hiddenBiggerThan(), '>'); + return s; + } + + public static int getWidth(List stringsToDisplay) { + int result = 1; + for (CharSequence s : stringsToDisplay) { + if (result < s.length()) { + result = s.length(); + } + } + return result; + } + + public static int getHeight(List stringsToDisplay) { + return stringsToDisplay.size(); + } + +} diff --git a/src/net/sourceforge/plantuml/UmlDiagram.java b/src/net/sourceforge/plantuml/UmlDiagram.java new file mode 100644 index 000000000..f06093260 --- /dev/null +++ b/src/net/sourceforge/plantuml/UmlDiagram.java @@ -0,0 +1,134 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5503 $ + * + */ +package net.sourceforge.plantuml; + +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; + +public abstract class UmlDiagram extends AbstractPSystem implements PSystem { + + private boolean rotation; + + private int minwidth = Integer.MAX_VALUE; + + private List title; + private List header; + private List 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 strings) { + this.title = strings; + } + + final public List 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 getHeader() { + return header; + } + + public final void setHeader(List header) { + this.header = header; + } + + public final List getFooter() { + return footer; + } + + public final void setFooter(List 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; + } + + final public Scale getScale() { + return scale; + } + +} diff --git a/src/net/sourceforge/plantuml/UmlDiagramType.java b/src/net/sourceforge/plantuml/UmlDiagramType.java new file mode 100644 index 000000000..bff9ea936 --- /dev/null +++ b/src/net/sourceforge/plantuml/UmlDiagramType.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4539 $ + * + */ +package net.sourceforge.plantuml; + +public enum UmlDiagramType { + SEQUENCE, STATE, CLASS, OBJECT, ACTIVITY, USECASE, COMPONENT, COMPOSITE +} diff --git a/src/net/sourceforge/plantuml/UmlSource.java b/src/net/sourceforge/plantuml/UmlSource.java new file mode 100644 index 000000000..d1e3f779f --- /dev/null +++ b/src/net/sourceforge/plantuml/UmlSource.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4768 $ + * + */ +package net.sourceforge.plantuml; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +final public class UmlSource { + + final private List source = new ArrayList(); + + @Deprecated + public UmlSource(UmlSource start) { + this.source.addAll(start.source); + } + + public UmlSource(List source) { + this.source.addAll(source); + } + + @Deprecated + public UmlSource() { + } + + public Iterator iterator() { + return source.iterator(); + } + + @Deprecated + public void append(String s) { + source.add(s); + } + + public String getPlainString() { + final StringBuilder sb = new StringBuilder(); + for (String s : source) { + sb.append(s); + sb.append('\n'); + } + return sb.toString(); + } + + public String getLine(int n) { + return source.get(n); + } + + public int getSize() { + return source.size(); + } + +} diff --git a/src/net/sourceforge/plantuml/UniqueSequence.java b/src/net/sourceforge/plantuml/UniqueSequence.java new file mode 100644 index 000000000..50c329fd4 --- /dev/null +++ b/src/net/sourceforge/plantuml/UniqueSequence.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3823 $ + * + */ +package net.sourceforge.plantuml; + +public class UniqueSequence { + + private static int cpt = 1; + + public static void reset() { + cpt = 1; + } + + public static int getValue() { + return cpt++; + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java new file mode 100644 index 000000000..bfe2afeb4 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java @@ -0,0 +1,192 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5223 $ + * + */ +package net.sourceforge.plantuml.activitydiagram; + +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; + +public class ActivityDiagram extends CucaDiagram { + + private IEntity lastEntityConsulted; + private IEntity lastEntityBrancheConsulted; + private ConditionalContext currentContext; + private boolean acceptOldSyntaxForBranch = true; + + private String getAutoBranch() { + return "#" + UniqueSequence.getValue(); + } + + public IEntity getOrCreate(String code, String display, EntityType type) { + final IEntity result; + if (entityExist(code)) { + result = super.getOrCreateEntity(code, type); + if (result.getType() != type) { + throw new IllegalArgumentException("Already known: " + code); + // return null; + } + } else { + result = createEntity(code, display, type); + } + updateLasts(result); + return result; + } + + public void startIf() { + final IEntity br = createEntity(getAutoBranch(), "", EntityType.BRANCH); + currentContext = new ConditionalContext(currentContext, br, Direction.DOWN); + } + + public void endif() { + currentContext = currentContext.getParent(); + } + + public IEntity getStart() { + return getOrCreate("start", "start", EntityType.CIRCLE_START); + } + + public IEntity getEnd() { + return getOrCreate("end", "end", EntityType.CIRCLE_END); + } + + final public Link getLastActivityLink() { + final List links = getLinks(); + for (int i = links.size() - 1; i >= 0; i--) { + final Link link = links.get(i); + if (link.getEntity1().getType() != EntityType.NOTE && link.getEntity2().getType() != EntityType.NOTE) { + return link; + } + } + return null; + } + + private void updateLasts(final IEntity result) { + if (result.getType() == EntityType.NOTE) { + return; + } + this.lastEntityConsulted = result; + if (result.getType() == EntityType.BRANCH) { + lastEntityBrancheConsulted = result; + } + } + + @Override + public Entity createEntity(String code, String display, EntityType type) { + final Entity result = super.createEntity(code, display, type); + updateLasts(result); + return result; + } + + public Entity createNote(String code, String display) { + return super.createEntity(code, display, EntityType.NOTE); + } + + final protected List getDotStrings() { + return Arrays.asList("nodesep=.20;", "ranksep=0.4;", "edge [fontsize=11,labelfontsize=11];", + "node [fontsize=11];"); + } + + public String getDescription() { + return "(" + entities().size() + " activities)"; + } + + public IEntity getLastEntityConsulted() { + return lastEntityConsulted; + } + + @Deprecated + public IEntity getLastEntityBrancheConsulted() { + return lastEntityBrancheConsulted; + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.ACTIVITY; + } + + public final ConditionalContext getCurrentContext() { + return currentContext; + } + + public final void setLastEntityConsulted(IEntity lastEntityConsulted) { + this.lastEntityConsulted = lastEntityConsulted; + } + + public final boolean isAcceptOldSyntaxForBranch() { + return acceptOldSyntaxForBranch; + } + + public final void setAcceptOldSyntaxForBranch(boolean acceptOldSyntaxForBranch) { + this.acceptOldSyntaxForBranch = acceptOldSyntaxForBranch; + } + + public IEntity createInnerActivity() { + // System.err.println("createInnerActivity A"); + final String code = "##" + UniqueSequence.getValue(); + final Group g = getOrCreateGroup(code, code, null, GroupType.INNER_ACTIVITY, getCurrentGroup()); + // g.setRankdir(Rankdir.LEFT_TO_RIGHT); + lastEntityConsulted = null; + lastEntityBrancheConsulted = null; + // System.err.println("createInnerActivity B "+getCurrentGroup()); + return g.getEntityCluster(); + } + + public void concurrentActivity(String name) { + // System.err.println("concurrentActivity A name=" + name+" "+getCurrentGroup()); + if (getCurrentGroup().getType() == GroupType.CONCURRENT_ACTIVITY) { + // getCurrentGroup().setRankdir(Rankdir.LEFT_TO_RIGHT); + endGroup(); + System.err.println("endgroup"); + } + // System.err.println("concurrentActivity A name=" + name+" "+getCurrentGroup()); + final String code = "##" + UniqueSequence.getValue(); + if (getCurrentGroup().getType() != GroupType.INNER_ACTIVITY) { + throw new IllegalStateException("type=" + getCurrentGroup().getType()); + } + final Group g = getOrCreateGroup(code, "code", null, GroupType.CONCURRENT_ACTIVITY, getCurrentGroup()); + lastEntityConsulted = null; + lastEntityBrancheConsulted = null; + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java new file mode 100644 index 000000000..5e85b9986 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5190 $ + * + */ +package net.sourceforge.plantuml.activitydiagram; + +import net.sourceforge.plantuml.activitydiagram.command.CommandElse; +import net.sourceforge.plantuml.activitydiagram.command.CommandEndPartition; +import net.sourceforge.plantuml.activitydiagram.command.CommandEndif; +import net.sourceforge.plantuml.activitydiagram.command.CommandIf; +import net.sourceforge.plantuml.activitydiagram.command.CommandInnerConcurrent; +import net.sourceforge.plantuml.activitydiagram.command.CommandLinkActivity2; +import net.sourceforge.plantuml.activitydiagram.command.CommandLinkLongActivity2; +import net.sourceforge.plantuml.activitydiagram.command.CommandMultilinesNoteActivity; +import net.sourceforge.plantuml.activitydiagram.command.CommandMultilinesNoteActivityLink; +import net.sourceforge.plantuml.activitydiagram.command.CommandNoteActivity; +import net.sourceforge.plantuml.activitydiagram.command.CommandNoteOnActivityLink; +import net.sourceforge.plantuml.activitydiagram.command.CommandPartition; +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; + +public class ActivityDiagramFactory extends AbstractUmlSystemCommandFactory { + + private ActivityDiagram system; + + public ActivityDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new ActivityDiagram(); + + addCommonCommands(system); + + addCommand(new CommandLinkActivity2(system)); + addCommand(new CommandPartition(system)); + addCommand(new CommandEndPartition(system)); + addCommand(new CommandLinkLongActivity2(system)); + + addCommand(new CommandNoteActivity(system)); + addCommand(new CommandMultilinesNoteActivity(system)); + + addCommand(new CommandNoteOnActivityLink(system)); + addCommand(new CommandMultilinesNoteActivityLink(system)); + + addCommand(new CommandIf(system)); + addCommand(new CommandElse(system)); + addCommand(new CommandEndif(system)); + addCommand(new CommandInnerConcurrent(system)); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java b/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java new file mode 100644 index 000000000..cc220e857 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/ConditionalContext.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.activitydiagram; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class ConditionalContext { + + private final IEntity branch; + private final Direction direction; + private final ConditionalContext parent; + + public ConditionalContext(ConditionalContext parent, IEntity branch, Direction direction) { + if (branch.getType() != EntityType.BRANCH) { + throw new IllegalArgumentException(); + } + this.branch = branch; + this.direction = direction; + this.parent = parent; + } + + public Direction getDirection() { + return direction; + } + + public final ConditionalContext getParent() { + return parent; + } + + public final IEntity getBranch() { + return branch; + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java new file mode 100644 index 000000000..7767de7b0 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class CommandElse extends SingleLineCommand { + + public CommandElse(ActivityDiagram diagram) { + super(diagram, "(?i)^else$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().getLastEntityConsulted() == null) { + return CommandExecutionResult.error("No if for this else"); + } + final IEntity branch = getSystem().getCurrentContext().getBranch(); + + getSystem().setLastEntityConsulted(branch); + getSystem().setAcceptOldSyntaxForBranch(false); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndPartition.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndPartition.java new file mode 100644 index 000000000..583e28737 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndPartition.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5048 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; + +public class CommandEndPartition extends SingleLineCommand { + + public CommandEndPartition(ActivityDiagram diagram) { + super(diagram, "(?i)^(end ?partition|\\})$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + if (currentPackage == null) { + return CommandExecutionResult.error("No partition defined"); + } + getSystem().endGroup(); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java new file mode 100644 index 000000000..1a54f414e --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; + +public class CommandEndif extends SingleLineCommand { + + public CommandEndif(ActivityDiagram diagram) { + super(diagram, "(?i)^endif$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().getLastEntityConsulted() == null) { + return CommandExecutionResult.error("No if for this endif"); + } + getSystem().endif(); + getSystem().setAcceptOldSyntaxForBranch(false); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java new file mode 100644 index 000000000..73cbfae3c --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java @@ -0,0 +1,88 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandIf extends SingleLineCommand { + + public CommandIf(ActivityDiagram diagram) { + super( + diagram, + "(?i)^(?:(\\(\\*\\))|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)?" + + "\\s*([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)?\\s*(?:\\[([^\\]*]+[^\\]]*)\\])?\\s*if\\s*\"([^\"]*)\"\\s*then$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final IEntity entity1 = CommandLinkActivity2.getEntity(getSystem(), arg, true); + + getSystem().startIf(); + + int lenght = 2; + + if (arg.get(5) != null) { + final String arrow = StringUtils.manageArrowForCuca(arg.get(5)); + lenght = arrow.length() - 1; + } + + final IEntity branch = getSystem().getCurrentContext().getBranch(); + + + Link link = new Link(entity1, branch, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), arg.get(6), lenght, null, + arg.get(7), getSystem().getLabeldistance(), getSystem().getLabelangle()); + if (arg.get(5) != null) { + final Direction direction = StringUtils.getArrowDirection(arg.get(5)); + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + } + + getSystem().addLink(link); + + getSystem().setAcceptOldSyntaxForBranch(false); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandInnerConcurrent.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandInnerConcurrent.java new file mode 100644 index 000000000..9cc70377b --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandInnerConcurrent.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; + +public class CommandInnerConcurrent extends SingleLineCommand { + + public CommandInnerConcurrent(ActivityDiagram diagram) { + super(diagram, "(?i)^--\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().getCurrentGroup() == null) { + return CommandExecutionResult.error("No inner activity"); + } + getSystem().concurrentActivity(arg.get(0)); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity2.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity2.java new file mode 100644 index 000000000..77bfa3b7d --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity2.java @@ -0,0 +1,125 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5024 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandLinkActivity2 extends SingleLineCommand { + + public CommandLinkActivity2(ActivityDiagram diagram) { + super( + diagram, + "(?i)^(?:(\\(\\*\\))|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)?" + + "\\s*([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)\\s*(?:\\[([^\\]*]+[^\\]]*)\\])?\\s*" + + "(?:(\\(\\*\\)|\\{)|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)$"); + } + + @Override + protected void actionIfCommandValid() { + getSystem().setAcceptOldSyntaxForBranch(false); + } + + static IEntity getEntity(ActivityDiagram system, List arg, final boolean start) { + if ("{".equals(arg.get(0))) { + return system.createInnerActivity(); + } + if ("(*)".equals(arg.get(0))) { + if (start) { + return system.getStart(); + } + return system.getEnd(); + } + if (arg.get(1) != null) { + return system.getOrCreate(arg.get(1), arg.get(1), EntityType.ACTIVITY); + } + if (arg.get(2) != null) { + return system.getOrCreate(arg.get(2), arg.get(2), EntityType.SYNCHRO_BAR); + } + if (arg.get(3) != null) { + final String code = arg.get(4) == null ? arg.get(3) : arg.get(4); + return system.getOrCreate(code, arg.get(3), EntityType.ACTIVITY); + } + if (start && arg.get(0) == null && arg.get(1) == null && arg.get(2) == null && arg.get(3) == null + && arg.get(4) == null) { + return system.getLastEntityConsulted(); + } + throw new UnsupportedOperationException(); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final IEntity entity1 = getEntity(getSystem(), arg, true); + final IEntity entity2 = getEntity(getSystem(), arg.subList(7, 12), false); + final String linkLabel = arg.get(6); + + final String arrow = StringUtils.manageArrowForCuca(arg.get(5)); + final int lenght = arrow.length() - 1; + + Link link = new Link(entity1, entity2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), linkLabel, lenght); + final Direction direction = StringUtils.getArrowDirection(arg.get(5)); + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + + getSystem().addLink(link); + + return CommandExecutionResult.ok(); + + } + + static EntityType getTypeFromString(String type, final EntityType circle) { + if (type == null) { + return EntityType.ACTIVITY; + } + if (type.equals("*")) { + return circle; + } + if (type.startsWith("=")) { + return EntityType.SYNCHRO_BAR; + } + throw new IllegalArgumentException(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java new file mode 100644 index 000000000..55df3cc02 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java @@ -0,0 +1,116 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5031 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandLinkLongActivity2 extends CommandMultilines { + + public CommandLinkLongActivity2(final ActivityDiagram diagram) { + super( + diagram, + "(?i)^(?:(\\(\\*\\))|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)?" + + "\\s*([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)\\s*(?:\\[([^\\]*]+[^\\]]*)\\])?\\s*\"([^\"]*?)\\s*$", + "(?i)^\\s*([^\"]*)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?$"); + } + + @Override + protected void actionIfCommandValid() { + getSystem().setAcceptOldSyntaxForBranch(false); + } + + public CommandExecutionResult execute(List lines) { + + // final IEntity lastEntityConsulted = + // getSystem().getLastEntityConsulted(); + + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final IEntity entity1 = CommandLinkActivity2.getEntity(getSystem(), line0, true); + final StringBuilder sb = new StringBuilder(); + + if (StringUtils.isNotEmpty(line0.get(7))) { + sb.append(line0.get(7)); + sb.append("\\n"); + } + for (int i = 1; i < lines.size() - 1; i++) { + sb.append(lines.get(i)); + if (i < lines.size() - 2) { + sb.append("\\n"); + } + } + + final List lineLast = StringUtils.getSplit(getEnding(), lines.get(lines.size() - 1)); + if (StringUtils.isNotEmpty(lineLast.get(0))) { + sb.append("\\n"); + sb.append(lineLast.get(0)); + } + + final String display = sb.toString(); + final String code = lineLast.get(1) == null ? display : lineLast.get(1); + + final Entity entity2 = getSystem().createEntity(code, display, EntityType.ACTIVITY); + + if (entity1 == null || entity2 == null) { + return CommandExecutionResult.error("No such entity"); + } + + final String arrow = StringUtils.manageArrowForCuca(line0.get(5)); + final int lenght = arrow.length() - 1; + + final String linkLabel = line0.get(6); + + Link link = new Link(entity1, entity2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), linkLabel, lenght); + final Direction direction = StringUtils.getArrowDirection(line0.get(5)); + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + + getSystem().addLink(link); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java new file mode 100644 index 000000000..984b0c378 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.command.Position; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandMultilinesNoteActivity extends CommandMultilines { + + public CommandMultilinesNoteActivity(final ActivityDiagram system) { + super(system, "(?i)^note\\s+(right|left|top|bottom)$", "(?i)^end ?note$"); + } + + public final CommandExecutionResult execute(List lines) { + + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final String pos = line0.get(0); + + IEntity activity = getSystem().getLastEntityConsulted(); + if (activity == null) { + activity = getSystem().getStart(); + } + + final List strings = lines.subList(1, lines.size() - 1); + final String s = StringUtils.getMergedLines(strings); + + final Entity note = getSystem().createEntity("GMN" + UniqueSequence.getValue(), s, EntityType.NOTE); + + final Link link; + + final Position position = Position.valueOf(pos.toUpperCase()).withRankdir(getSystem().getRankdir()); + + final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getDashed(); + + if (position == Position.RIGHT) { + link = new Link(activity, note, type, null, 1); + } else if (position == Position.LEFT) { + link = new Link(note, activity, type, null, 1); + } else if (position == Position.BOTTOM) { + link = new Link(activity, note, type, null, 2); + } else if (position == Position.TOP) { + link = new Link(note, activity, type, null, 2); + } else { + throw new IllegalArgumentException(); + } + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java new file mode 100644 index 000000000..70cf64040 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.cucadiagram.Link; + +public class CommandMultilinesNoteActivityLink extends CommandMultilines { + + public CommandMultilinesNoteActivityLink(final ActivityDiagram system) { + super(system, "(?i)^note\\s+on\\s+link$", "(?i)^end ?note$"); + } + + public final CommandExecutionResult execute(List lines) { + + final List strings = lines.subList(1, lines.size() - 1); + final String s = StringUtils.getMergedLines(strings); + + final Link link = getSystem().getLastActivityLink(); + if (link == null) { + return CommandExecutionResult.error("Nothing to note"); + } + link.setNote(s); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandNoteActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandNoteActivity.java new file mode 100644 index 000000000..4c623a1e9 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandNoteActivity.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.Position; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandNoteActivity extends SingleLineCommand { + + public CommandNoteActivity(ActivityDiagram diagram) { + super(diagram, "(?i)^note\\s+(right|left|top|bottom)\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String pos = arg.get(0); + final Entity note = getSystem().createNote("GN" + UniqueSequence.getValue(), arg.get(1)); + + IEntity activity = getSystem().getLastEntityConsulted(); + if (activity == null) { + activity = getSystem().getStart(); + } + + final Position position = Position.valueOf(pos.toUpperCase()).withRankdir(getSystem().getRankdir()); + final Link link; + + final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getDashed(); + if (position == Position.RIGHT) { + link = new Link(activity, note, type, null, 1); + } else if (position == Position.LEFT) { + link = new Link(note, activity, type, null, 1); + } else if (position == Position.BOTTOM) { + link = new Link(activity, note, type, null, 2); + } else if (position == Position.TOP) { + link = new Link(note, activity, type, null, 2); + } else { + throw new IllegalArgumentException(); + } + getSystem().addLink(link); + return CommandExecutionResult.ok(); + + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandNoteOnActivityLink.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandNoteOnActivityLink.java new file mode 100644 index 000000000..924cf7878 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandNoteOnActivityLink.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Link; + +public class CommandNoteOnActivityLink extends SingleLineCommand { + + public CommandNoteOnActivityLink(ActivityDiagram diagram) { + super(diagram, "(?i)^note\\s+on\\s+link\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Link link = getSystem().getLastActivityLink(); + if (link == null) { + return CommandExecutionResult.error("No link defined"); + } + link.setNote(arg.get(0)); + return CommandExecutionResult.ok(); + + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java new file mode 100644 index 000000000..f2379baea --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5048 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class CommandPartition extends SingleLineCommand { + + public CommandPartition(ActivityDiagram diagram) { + super(diagram, "(?i)^partition\\s+(\"[^\"]+\"|\\S+)\\s*(#[0-9a-fA-F]{6}|#?\\w+)?\\s*\\{?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + final Group currentPackage = getSystem().getCurrentGroup(); + final Group p = getSystem().getOrCreateGroup(code, code, null, GroupType.PACKAGE, currentPackage); + p.setBold(true); + final String color = arg.get(1); + if (color != null) { + p.setBackColor(new HtmlColor(color)); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java new file mode 100644 index 000000000..242ae7fde --- /dev/null +++ b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java @@ -0,0 +1,231 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5354 $ + * + */ +package net.sourceforge.plantuml.ant; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.DirWatcher; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.GeneratedImage; +import net.sourceforge.plantuml.Option; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.SourceFileReader; +import net.sourceforge.plantuml.preproc.Defines; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileList; +import org.apache.tools.ant.types.FileSet; + +// +// +// +// +// +// +// +// +// + +// Carriage Return in UTF-8 XML: +// Line Feed in UTF-8 XML: +public class PlantUmlTask extends Task { + + private String dir = null; + private final Option option = new Option(); + private List filesets = new ArrayList(); + private List filelists = new ArrayList(); + + /** + * Add a set of files to touch + */ + public void addFileset(FileSet set) { + filesets.add(set); + } + + /** + * Add a filelist to touch + */ + public void addFilelist(FileList list) { + filelists.add(list); + } + + // The method executing the task + @Override + public void execute() throws BuildException { + + this.log("Starting PlantUML"); + + try { + if (dir != null) { + processingSingleDirectory(new File(dir)); + } + for (FileSet fileSet : filesets) { + manageFileSet(fileSet); + } + for (FileList fileList : filelists) { + manageFileList(fileList); + } + } catch (IOException e) { + e.printStackTrace(); + throw new BuildException(e.toString()); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new BuildException(e.toString()); + } + + } + + private void manageFileList(FileList fl) throws IOException, InterruptedException { + final File fromDir = fl.getDir(getProject()); + + final String[] srcFiles = fl.getFiles(getProject()); + + for (String src : srcFiles) { + final File f = new File(fromDir, src); + processingSingleFile(f); + } + } + + private void manageFileSet(FileSet fs) throws IOException, InterruptedException { + final DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + final File fromDir = fs.getDir(getProject()); + + final String[] srcFiles = ds.getIncludedFiles(); + final String[] srcDirs = ds.getIncludedDirectories(); + + for (String src : srcFiles) { + final File f = new File(fromDir, src); + processingSingleFile(f); + } + + for (String src : srcDirs) { + final File dir = new File(fromDir, src); + processingSingleDirectory(dir); + } + + } + + private void processingSingleFile(final File f) throws IOException, InterruptedException { + this.log("Processing " + f.getAbsolutePath()); + final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), option + .getConfig(), option.getCharset(), option.getFileFormat()); + final Collection result = sourceFileReader.getGeneratedImages(); + for (GeneratedImage g : result) { + this.log(g + " " + g.getDescription()); + } + } + + private void processingSingleDirectory(File f) throws IOException, InterruptedException { + if (f.exists() == false) { + final String s = "The file " + f.getAbsolutePath() + " does not exists."; + this.log(s); + throw new BuildException(s); + } + final DirWatcher dirWatcher = new DirWatcher(f, option, Option.getPattern()); + final Collection result = dirWatcher.buildCreatedFiles(); + for (GeneratedImage g : result) { + this.log(g + " " + g.getDescription()); + } + } + + public void setDir(String s) { + this.dir = s; + } + + public void setOutput(String s) { + option.setOutputDir(new File(s)); + } + + public void setCharset(String s) { + option.setCharset(s); + } + + public void setConfig(String s) { + try { + option.initConfig(s); + } catch (IOException e) { + log("Error reading " + s); + } + } + + public void setKeepTmpFiles(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setKeepTmpFiles(true); + } + } + + public void setVerbose(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setVerbose(true); + } + } + + public void setFormat(String s) { + if ("eps".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.EPS); + } + if ("svg".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.SVG); + } + if ("txt".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.ATXT); + } + if ("utxt".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.UTXT); + } + } + + public void setGraphvizDot(String s) { + OptionFlags.getInstance().setDotExecutable(s); + } + + public void setForcegd(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setForceGd(true); + } + } + + public void setForcecairo(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setForceCairo(true); + } + } + +} diff --git a/src/net/sourceforge/plantuml/ant/PlantuTask.java b/src/net/sourceforge/plantuml/ant/PlantuTask.java new file mode 100644 index 000000000..75cf2128a --- /dev/null +++ b/src/net/sourceforge/plantuml/ant/PlantuTask.java @@ -0,0 +1,232 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5354 $ + * + */ +package net.sourceforge.plantuml.ant; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.DirWatcher; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.GeneratedImage; +import net.sourceforge.plantuml.Option; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.SourceFileReader; +import net.sourceforge.plantuml.preproc.Defines; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileList; +import org.apache.tools.ant.types.FileSet; + +// +// +// +// +// +// +// +// +// + +// Carriage Return in UTF-8 XML: +// Line Feed in UTF-8 XML: +public class PlantuTask extends Task { + + private String dir = null; + private final Option option = new Option(); + private List filesets = new ArrayList(); + private List filelists = new ArrayList(); + + /** + * Add a set of files to touch + */ + public void addFileset(FileSet set) { + filesets.add(set); + } + + /** + * Add a filelist to touch + */ + public void addFilelist(FileList list) { + filelists.add(list); + } + + // The method executing the task + @Override + public void execute() throws BuildException { + + this.log("Starting PlantUML"); + + try { + if (dir != null) { + processingSingleDirectory(new File(dir)); + } + for (FileSet fileSet : filesets) { + manageFileSet(fileSet); + } + for (FileList fileList : filelists) { + manageFileList(fileList); + } + } catch (IOException e) { + e.printStackTrace(); + throw new BuildException(e.toString()); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new BuildException(e.toString()); + } + + } + + private void manageFileList(FileList fl) throws IOException, InterruptedException { + final File fromDir = fl.getDir(getProject()); + + final String[] srcFiles = fl.getFiles(getProject()); + + for (String src : srcFiles) { + final File f = new File(fromDir, src); + processingSingleFile(f); + } + } + + private void manageFileSet(FileSet fs) throws IOException, InterruptedException { + final DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + final File fromDir = fs.getDir(getProject()); + + final String[] srcFiles = ds.getIncludedFiles(); + final String[] srcDirs = ds.getIncludedDirectories(); + + for (String src : srcFiles) { + final File f = new File(fromDir, src); + processingSingleFile(f); + } + + for (String src : srcDirs) { + final File dir = new File(fromDir, src); + processingSingleDirectory(dir); + } + + } + + private void processingSingleFile(final File f) throws IOException, InterruptedException { + this.log("Processing " + f.getAbsolutePath()); + final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), option + .getConfig(), option.getCharset(), option.getFileFormat()); + final Collection result = sourceFileReader.getGeneratedImages(); + for (GeneratedImage g : result) { + this.log(g + " " + g.getDescription()); + } + } + + private void processingSingleDirectory(File f) throws IOException, InterruptedException { + if (f.exists() == false) { + final String s = "The file " + f.getAbsolutePath() + " does not exists."; + this.log(s); + throw new BuildException(s); + } + final DirWatcher dirWatcher = new DirWatcher(f, option, Option.getPattern()); + final Collection result = dirWatcher.buildCreatedFiles(); + for (GeneratedImage g : result) { + this.log(g + " " + g.getDescription()); + } + } + + public void setDir(String s) { + this.dir = s; + } + + public void setOutput(String s) { + option.setOutputDir(new File(s)); + } + + public void setCharset(String s) { + option.setCharset(s); + } + + public void setConfig(String s) { + try { + option.initConfig(s); + } catch (IOException e) { + log("Error reading " + s); + } + } + + public void setKeepTmpFiles(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setKeepTmpFiles(true); + } + } + + public void setVerbose(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setVerbose(true); + } + } + + public void setFormat(String s) { + if ("eps".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.EPS); + } + if ("svg".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.SVG); + } + if ("txt".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.ATXT); + } + if ("utxt".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.UTXT); + } + } + + public void setGraphvizDot(String s) { + OptionFlags.getInstance().setDotExecutable(s); + } + + public void setForcegd(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setForceGd(true); + } + } + + public void setForcecairo(String s) { + if ("true".equalsIgnoreCase(s)) { + OptionFlags.getInstance().setForceCairo(true); + } + } + + +} diff --git a/src/net/sourceforge/plantuml/applet/VersionApplet.java b/src/net/sourceforge/plantuml/applet/VersionApplet.java new file mode 100644 index 000000000..7108f416b --- /dev/null +++ b/src/net/sourceforge/plantuml/applet/VersionApplet.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.applet; + +import java.applet.Applet; +import java.awt.Graphics; + +import net.sourceforge.plantuml.version.Version; + +public class VersionApplet extends Applet { + + @Override + public void init() { + super.init(); + } + + @Override + public void start() { + super.start(); + } + + @Override + public void paint(Graphics g) { + g.drawString("" + Version.version(), 0, 10); + } +} diff --git a/src/net/sourceforge/plantuml/asciiart/BasicCharArea.java b/src/net/sourceforge/plantuml/asciiart/BasicCharArea.java new file mode 100644 index 000000000..e0eeba873 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/BasicCharArea.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3826 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.io.PrintStream; +import java.util.List; + +public interface BasicCharArea { + + int getWidth(); + + int getHeight(); + + void drawChar(char c, int x, int y); + + void fillRect(char c, int x, int y, int width, int height); + + void drawStringLR(String string, int x, int y); + + void drawStringTB(String string, int x, int y); + + String getLine(int line); + + void print(PrintStream ps); + + List getLines(); + + void drawHLine(char c, int line, int col1, int col2); + void drawHLine(char c, int line, int col1, int col2, char ifFound, char thenUse); + + void drawVLine(char c, int col, int line1, int line2); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/asciiart/BasicCharAreaImpl.java b/src/net/sourceforge/plantuml/asciiart/BasicCharAreaImpl.java new file mode 100644 index 000000000..c822cf160 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/BasicCharAreaImpl.java @@ -0,0 +1,176 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5178 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class BasicCharAreaImpl implements BasicCharArea { + + private int charSize1 = 160; + private int charSize2 = 160; + + private int width; + private int height; + + private char chars[][]; + + public BasicCharAreaImpl() { + chars = new char[charSize1][charSize2]; + for (int i = 0; i < charSize1; i++) { + for (int j = 0; j < charSize2; j++) { + chars[i][j] = ' '; + } + } + } + + public final int getWidth() { + return width; + } + + public final int getHeight() { + return height; + } + + public void drawChar(char c, int x, int y) { + ensurePossible(x, y); + chars[x][y] = c; + if (x >= width) { + width = x + 1; + } + if (y >= height) { + height = y + 1; + } + } + + private void ensurePossible(int x, int y) { + int newCharSize1 = charSize1; + int newCharSize2 = charSize2; + while (x >= newCharSize1) { + newCharSize1 *= 2; + } + while (y >= newCharSize2) { + newCharSize2 *= 2; + } + if (newCharSize1 != charSize1 || newCharSize2 != charSize2) { + final char newChars[][] = new char[newCharSize1][newCharSize2]; + for (int i = 0; i < newCharSize1; i++) { + for (int j = 0; j < newCharSize2; j++) { + char c = ' '; + if (i < charSize1 && j < charSize2) { + c = chars[i][j]; + } + newChars[i][j] = c; + } + } + this.chars = newChars; + this.charSize1 = newCharSize1; + this.charSize2 = newCharSize2; + } + + } + + public void drawStringLR(String string, int x, int y) { + for (int i = 0; i < string.length(); i++) { + drawChar(string.charAt(i), x + i, y); + } + } + + public void drawStringTB(String string, int x, int y) { + for (int i = 0; i < string.length(); i++) { + drawChar(string.charAt(i), x, y + i); + } + } + + public String getLine(int line) { + final StringBuilder sb = new StringBuilder(charSize1); + for (int x = 0; x < width; x++) { + sb.append(chars[x][line]); + } + return sb.toString(); + } + + public void print(PrintStream ps) { + for (String s : getLines()) { + ps.println(s); + } + } + + public List getLines() { + final List result = new ArrayList(height); + for (int y = 0; y < height; y++) { + result.add(getLine(y)); + } + return Collections.unmodifiableList(result); + } + + public void drawHLine(char c, int line, int col1, int col2) { + for (int x = col1; x < col2; x++) { + this.drawChar(c, x, line); + } + } + + public void drawHLine(char c, int line, int col1, int col2, char ifFound, char thenUse) { + for (int x = col1; x < col2; x++) { + ensurePossible(x, line); + if (this.chars[x][line] == ifFound) { + this.drawChar(thenUse, x, line); + } else { + this.drawChar(c, x, line); + } + } + } + + public void drawVLine(char c, int col, int line1, int line2) { + for (int y = line1; y < line2; y++) { + this.drawChar(c, col, y); + } + } + + @Override + public String toString() { + return getLines().toString(); + } + + public void fillRect(char c, int x, int y, int width, int height) { + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + drawChar(c, x + i, y + j); + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextActiveLine.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextActiveLine.java new file mode 100644 index 000000000..5014122ac --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextActiveLine.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextActiveLine implements Component { + + private final FileFormat fileFormat; + + public ComponentTextActiveLine(FileFormat fileFormat) { + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + if (fileFormat == FileFormat.UTXT) { + charArea.fillRect(' ', 0, 0, width, height); + charArea.drawBoxSimpleUnicode(0, 0, width, height); + charArea.drawChar('\u2534', width/2, 0); + charArea.drawChar('\u252c', width/2, height-1); + } else { + charArea.fillRect('X', 0, 0, width, height); + charArea.drawBoxSimple(0, 0, width, height); + } + } + + public double getPreferredHeight(StringBounder stringBounder) { + return 0; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return 3; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextActor.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextActor.java new file mode 100644 index 000000000..7df0e1651 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextActor.java @@ -0,0 +1,102 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextActor implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextActor(ComponentType type, List stringsToDisplay, FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + // final int textWidth = StringUtils.getWidth(stringsToDisplay); + final int height = (int) dimensionToUse.getHeight(); + charArea.fillRect(' ', 0, 0, width, height); + + final int xman = width / 2 - 1; + if (type == ComponentType.ACTOR_HEAD) { + charArea.drawStringsLR(stringsToDisplay, 1, getStickManHeight()); + if (fileFormat == FileFormat.UTXT) { + charArea.drawStickManUnicode(xman, 0); + } else { + charArea.drawStickMan(xman, 0); + } + } else if (type == ComponentType.ACTOR_TAIL) { + charArea.drawStringsLR(stringsToDisplay, 1, 0); + if (fileFormat == FileFormat.UTXT) { + charArea.drawStickManUnicode(xman, 1); + } else { + charArea.drawStickMan(xman, 1); + } + } else { + assert false; + } + } + + private int getStickManHeight() { + if (fileFormat == FileFormat.UTXT) { + return UmlCharArea.STICKMAN_UNICODE_HEIGHT; + } + return UmlCharArea.STICKMAN_HEIGHT; + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + getStickManHeight(); + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 2; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextArrow.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextArrow.java new file mode 100644 index 000000000..ad777309f --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextArrow.java @@ -0,0 +1,92 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextArrow implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextArrow(ComponentType type, List stringsToDisplay, FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + final int textWidth = StringUtils.getWidth(stringsToDisplay); + + final int yarrow = height - 2; + charArea.drawHLine(fileFormat == FileFormat.UTXT ? '\u2500' : '-', yarrow, 1, width); + if (type == ComponentType.DOTTED_ARROW || type == ComponentType.RETURN_DOTTED_ARROW) { + for (int i = 1; i < width; i += 2) { + charArea.drawChar(' ', i, yarrow); + } + } + + if (type == ComponentType.ARROW || type == ComponentType.DOTTED_ARROW) { + charArea.drawChar('>', width - 1, yarrow); + } else if (type == ComponentType.RETURN_ARROW || type == ComponentType.RETURN_DOTTED_ARROW) { + charArea.drawChar('<', 1, yarrow); + } else { + throw new UnsupportedOperationException(); + } + charArea.drawStringsLR(stringsToDisplay, (width - textWidth) / 2, 0); + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + 2; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 2; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextDivider.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextDivider.java new file mode 100644 index 000000000..d27d4980c --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextDivider.java @@ -0,0 +1,94 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextDivider implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextDivider(ComponentType type, List stringsToDisplay, FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int textWidth = StringUtils.getWidth(stringsToDisplay); + // final int height = (int) dimensionToUse.getHeight(); + + final int textPos = (width - textWidth - 1) / 2; + final String desc = " " + stringsToDisplay.get(0).toString(); + + if (fileFormat == FileFormat.UTXT) { + charArea.drawHLine('\u2550', 2, 0, width, '\u2502', '\u256a'); + charArea.drawStringLR(desc, textPos, 2); + + charArea.drawHLine('\u2550', 1, textPos - 1, textPos + desc.length() + 1, '\u2502', '\u2567'); + charArea.drawHLine('\u2550', 3, textPos - 1, textPos + desc.length() + 1, '\u2502', '\u2564'); + + charArea.drawStringTB("\u2554\u2563\u255a", textPos - 1, 1); + charArea.drawStringTB("\u2557\u2560\u255d", textPos + desc.length(), 1); + } else { + charArea.drawHLine('=', 2, 0, width); + charArea.drawStringLR(desc, textPos, 2); + charArea.drawHLine('=', 1, textPos - 1, textPos + desc.length() + 1); + charArea.drawHLine('=', 3, textPos - 1, textPos + desc.length() + 1); + } + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + 4; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 2; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingBody.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingBody.java new file mode 100644 index 000000000..b02cc0fa9 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingBody.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextGroupingBody implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextGroupingBody(ComponentType type, List stringsToDisplay, + FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + + if (fileFormat == FileFormat.UTXT) { + charArea.drawVLine('\u2551', 0, 0, height); + charArea.drawVLine('\u2551', width - 1, 0, height); + charArea.drawHLine('\u2550', height - 1, 1, width - 1, '\u2502', '\u256a'); + charArea.drawChar('\u2560', 0, height - 1); + charArea.drawChar('\u2563', width - 1, height - 1); + } else { + charArea.drawVLine('!', 0, 0, height); + charArea.drawVLine('!', width - 1, 0, height); + charArea.drawHLine('~', height - 1, 1, width - 1); + } + } + + public double getPreferredHeight(StringBounder stringBounder) { + return 1; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingElse.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingElse.java new file mode 100644 index 000000000..27b6d8e65 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingElse.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextGroupingElse implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextGroupingElse(ComponentType type, List stringsToDisplay, + FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + // final int width = (int) dimensionToUse.getWidth(); + // final int height = (int) dimensionToUse.getHeight(); + + if (stringsToDisplay.get(0) != null) { + charArea.drawStringLR("[" + stringsToDisplay.get(0) + "]", 2, 0); + } + + // charArea.fillRect('E', 0, 0, width, height); + } + + public double getPreferredHeight(StringBounder stringBounder) { + return 1; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingHeader.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingHeader.java new file mode 100644 index 000000000..fe5166d44 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingHeader.java @@ -0,0 +1,103 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextGroupingHeader implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextGroupingHeader(ComponentType type, List stringsToDisplay, + FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + + // charArea.fillRect('G', 0, 0, width, height); + final String text = stringsToDisplay.get(0).toString(); + + if (fileFormat == FileFormat.UTXT) { + charArea.drawHLine('\u2550', 0, 1, width - 1, '\u2502', '\u256a'); + charArea.drawStringLR(text.toUpperCase() + " /", 2, 1); + charArea.drawHLine('\u2500', 2, 1, text.length() + 4); + charArea.drawVLine('\u2551', 0, 1, height + 3); + charArea.drawVLine('\u2551', width - 1, 1, height + 3); + charArea.drawChar('\u255f', 0, 2); + charArea.drawStringTB("\u2564\u2502\u2518", text.length() + 4, 0); + charArea.drawChar('\u2554', 0, 0); + charArea.drawChar('\u2557', width - 1, 0); + } else { + charArea.drawHLine('_', 0, 0, width - 1); + charArea.drawStringLR(text.toUpperCase() + " /", 2, 1); + charArea.drawHLine('_', 2, 1, text.length() + 3); + charArea.drawChar('/', text.length() + 3, 2); + charArea.drawVLine('!', 0, 1, height + 3); + charArea.drawVLine('!', width - 1, 1, height + 3); + } + + if (stringsToDisplay.size() > 1) { + final String comment = stringsToDisplay.get(1).toString(); + charArea.drawStringLR(comment, text.length() + 7, 1); + + } + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + 2; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 2; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingTail.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingTail.java new file mode 100644 index 000000000..5db01e7a8 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextGroupingTail.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextGroupingTail implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextGroupingTail(ComponentType type, List stringsToDisplay, + FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + + // charArea.fillRect('T', 0, 0, width, height); + if (fileFormat == FileFormat.UTXT) { + charArea.drawChar('\u255a', 0, height - 1); + charArea.drawChar('\u255d', width - 1, height - 1); + } + } + + public double getPreferredHeight(StringBounder stringBounder) { + return 1; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextLine.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextLine.java new file mode 100644 index 000000000..71ce1304e --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextLine.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextLine implements Component { + + private final FileFormat fileFormat; + + public ComponentTextLine(FileFormat fileFormat) { + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + if (fileFormat == FileFormat.UTXT) { + charArea.drawVLine('\u2502', (width - 1) / 2, 0, height - 1); + } else { + charArea.drawVLine('|', (width - 1) / 2, 0, height - 1); + } + } + + public double getPreferredHeight(StringBounder stringBounder) { + return 0; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return 3; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextNote.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextNote.java new file mode 100644 index 000000000..99d5ced52 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextNote.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextNote implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextNote(ComponentType type, List stringsToDisplay, FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth() - 1; + final int height = (int) dimensionToUse.getHeight(); + charArea.fillRect(' ', 2, 1, width - 3, height - 2); + if (fileFormat == FileFormat.UTXT) { + charArea.drawNoteSimpleUnicode(2, 0, width - 2, height); + } else { + charArea.drawNoteSimple(2, 0, width - 2, height); + } + charArea.drawStringsLR(stringsToDisplay, 3, 1); + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + 2; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 7; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextParticipant.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextParticipant.java new file mode 100644 index 000000000..58fa9f7f0 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextParticipant.java @@ -0,0 +1,94 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextParticipant implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextParticipant(ComponentType type, List stringsToDisplay, + FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight(); + charArea.fillRect(' ', 0, 0, width, height); + if (fileFormat == FileFormat.UTXT) { + charArea.drawBoxSimpleUnicode(0, 0, width, height); + if (type == ComponentType.PARTICIPANT_TAIL) { + charArea.drawChar('\u2534', (width - 1) / 2, 0); + } + if (type == ComponentType.PARTICIPANT_HEAD) { + charArea.drawChar('\u252c', (width - 1) / 2, height - 1); + } + } else { + charArea.drawBoxSimple(0, 0, width, height); + if (type == ComponentType.PARTICIPANT_TAIL) { + charArea.drawChar('+', (width - 1) / 2, 0); + } + if (type == ComponentType.PARTICIPANT_HEAD) { + charArea.drawChar('+', (width - 1) / 2, height - 1); + } + } + charArea.drawStringsLR(stringsToDisplay, 1, 1); + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + 2; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 2; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/ComponentTextSelfArrow.java b/src/net/sourceforge/plantuml/asciiart/ComponentTextSelfArrow.java new file mode 100644 index 000000000..5d6ed1a62 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/ComponentTextSelfArrow.java @@ -0,0 +1,101 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class ComponentTextSelfArrow implements Component { + + private final ComponentType type; + private final List stringsToDisplay; + private final FileFormat fileFormat; + + public ComponentTextSelfArrow(ComponentType type, List stringsToDisplay, + FileFormat fileFormat) { + this.type = type; + this.stringsToDisplay = stringsToDisplay; + this.fileFormat = fileFormat; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final UmlCharArea charArea = ((UGraphicTxt) ug).getCharArea(); + final int width = (int) dimensionToUse.getWidth(); + final int height = (int) dimensionToUse.getHeight() - 1; + + charArea.fillRect(' ', 0, 0, width, height); + + if (fileFormat == FileFormat.UTXT) { + if (type == ComponentType.SELF_ARROW) { + charArea.drawStringLR("\u2500\u2500\u2500\u2500\u2510", 0, 0); + charArea.drawStringLR("\u2502", 4, 1); + charArea.drawStringLR("<\u2500\u2500\u2500\u2518", 0, 2); + } else if (type == ComponentType.DOTTED_SELF_ARROW) { + charArea.drawStringLR("\u2500 \u2500 \u2510", 0, 0); + charArea.drawStringLR("|", 4, 1); + charArea.drawStringLR("< \u2500 \u2518", 0, 2); + } + } else { + if (type == ComponentType.SELF_ARROW) { + charArea.drawStringLR("----.", 0, 0); + charArea.drawStringLR("|", 4, 1); + charArea.drawStringLR("<---'", 0, 2); + } else if (type == ComponentType.DOTTED_SELF_ARROW) { + charArea.drawStringLR("- - .", 0, 0); + charArea.drawStringLR("|", 4, 1); + charArea.drawStringLR("< - '", 0, 2); + } + } + + charArea.drawStringsLR(stringsToDisplay, 6, 1); + } + + public double getPreferredHeight(StringBounder stringBounder) { + return StringUtils.getHeight(stringsToDisplay) + 3; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return StringUtils.getWidth(stringsToDisplay) + 6; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/TextSkin.java b/src/net/sourceforge/plantuml/asciiart/TextSkin.java new file mode 100644 index 000000000..210e3899a --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/TextSkin.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5140 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Skin; + +public class TextSkin implements Skin { + + private final FileFormat fileFormat; + + public TextSkin(FileFormat fileFormat) { + this.fileFormat = fileFormat; + } + + public Component createComponent(ComponentType type, ISkinParam param, List stringsToDisplay) { + if (type == ComponentType.PARTICIPANT_HEAD || type == ComponentType.PARTICIPANT_TAIL) { + return new ComponentTextParticipant(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.ACTOR_HEAD || type == ComponentType.ACTOR_TAIL) { + return new ComponentTextActor(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.ARROW || type == ComponentType.RETURN_ARROW || type == ComponentType.DOTTED_ARROW + || type == ComponentType.RETURN_DOTTED_ARROW) { + return new ComponentTextArrow(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.SELF_ARROW || type == ComponentType.DOTTED_SELF_ARROW) { + return new ComponentTextSelfArrow(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.PARTICIPANT_LINE || type == ComponentType.ACTOR_LINE) { + return new ComponentTextLine(fileFormat); + } + if (type == ComponentType.ALIVE_LINE) { + return new ComponentTextActiveLine(fileFormat); + } + if (type == ComponentType.NOTE) { + return new ComponentTextNote(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.DIVIDER) { + return new ComponentTextDivider(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.GROUPING_HEADER) { + return new ComponentTextGroupingHeader(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.GROUPING_BODY) { + return new ComponentTextGroupingBody(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.GROUPING_TAIL) { + return new ComponentTextGroupingTail(type, stringsToDisplay, fileFormat); + } + if (type == ComponentType.GROUPING_ELSE) { + return new ComponentTextGroupingElse(type, stringsToDisplay, fileFormat); + } + throw new UnsupportedOperationException(type.toString()); + } + + public Object getProtocolVersion() { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/TextStringBounder.java b/src/net/sourceforge/plantuml/asciiart/TextStringBounder.java new file mode 100644 index 000000000..407d6e753 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/TextStringBounder.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4246 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.awt.Font; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; + +public class TextStringBounder implements StringBounder { + + public Dimension2D calculateDimension(Font font, String text) { + return new Dimension2DDouble(text.length(), 1); + } + +} diff --git a/src/net/sourceforge/plantuml/asciiart/TranslatedCharArea.java b/src/net/sourceforge/plantuml/asciiart/TranslatedCharArea.java new file mode 100644 index 000000000..ecb7effe7 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/TranslatedCharArea.java @@ -0,0 +1,133 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5109 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.io.PrintStream; +import java.util.Collection; +import java.util.List; + +public class TranslatedCharArea implements UmlCharArea { + + private final int dx; + private final int dy; + private final UmlCharArea charArea; + + public TranslatedCharArea(UmlCharArea charArea, int dx, int dy) { + this.charArea = charArea; + this.dx = dx; + this.dy = dy; + } + + public void drawBoxSimple(int x, int y, int width, int height) { + charArea.drawBoxSimple(x + dx, y + dy, width, height); + + } + + public void drawBoxSimpleUnicode(int x, int y, int width, int height) { + charArea.drawBoxSimpleUnicode(x + dx, y + dy, width, height); + } + + public void drawNoteSimple(int x, int y, int width, int height) { + charArea.drawNoteSimple(x + dx, y + dy, width, height); + } + + public void drawNoteSimpleUnicode(int x, int y, int width, int height) { + charArea.drawNoteSimpleUnicode(x + dx, y + dy, width, height); + } + + + + public void drawStickMan(int x, int y) { + charArea.drawStickMan(x + dx, y + dy); + } + + public void drawStickManUnicode(int x, int y) { + charArea.drawStickManUnicode(x + dx, y + dy); + } + + + public void drawChar(char c, int x, int y) { + charArea.drawChar(c, x + dx, y + dy); + } + + public void drawHLine(char c, int line, int col1, int col2) { + charArea.drawHLine(c, line + dy, col1 + dx, col2 + dx); + } + public void drawHLine(char c, int line, int col1, int col2, char ifFound, char thenUse) { + charArea.drawHLine(c, line + dy, col1 + dx, col2 + dx, ifFound, thenUse); + } + + public void drawStringLR(String string, int x, int y) { + charArea.drawStringLR(string, x + dx, y + dy); + } + + public void drawStringTB(String string, int x, int y) { + charArea.drawStringTB(string, x + dx, y + dy); + } + + public void drawVLine(char c, int col, int line1, int line2) { + charArea.drawVLine(c, col + dx, line1 + dy, line2 + dy); + } + + public int getHeight() { + return charArea.getHeight(); + } + + public int getWidth() { + return charArea.getWidth(); + } + + public String getLine(int line) { + return charArea.getLine(line); + } + + public List getLines() { + return charArea.getLines(); + } + + public void print(PrintStream ps) { + charArea.print(ps); + } + + public void drawStringsLR(Collection strings, int x, int y) { + charArea.drawStringsLR(strings, x + dx, y + dy); + } + + public void fillRect(char c, int x, int y, int width, int height) { + charArea.fillRect(c, x + dx, y + dy, width, height); + } + + + +} diff --git a/src/net/sourceforge/plantuml/asciiart/UmlCharArea.java b/src/net/sourceforge/plantuml/asciiart/UmlCharArea.java new file mode 100644 index 000000000..3e00a3066 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/UmlCharArea.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3826 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.util.Collection; + +public interface UmlCharArea extends BasicCharArea { + + int STICKMAN_HEIGHT = 5; + int STICKMAN_UNICODE_HEIGHT = 6; + + void drawBoxSimple(int x, int y, int width, int height); + + void drawBoxSimpleUnicode(int x, int y, int width, int height); + + void drawNoteSimple(int x, int y, int width, int height); + + void drawNoteSimpleUnicode(int x, int y, int width, int height); + + void drawStickMan(int x, int y); + + void drawStickManUnicode(int x, int y); + + void drawStringsLR(Collection strings, int x, int y); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/asciiart/UmlCharAreaImpl.java b/src/net/sourceforge/plantuml/asciiart/UmlCharAreaImpl.java new file mode 100644 index 000000000..522d189b1 --- /dev/null +++ b/src/net/sourceforge/plantuml/asciiart/UmlCharAreaImpl.java @@ -0,0 +1,122 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5156 $ + * + */ +package net.sourceforge.plantuml.asciiart; + +import java.util.Collection; + +public class UmlCharAreaImpl extends BasicCharAreaImpl implements UmlCharArea { + + public void drawBoxSimple(int x, int y, int width, int height) { + this.drawHLine('-', y, x + 1, x + width - 1); + this.drawHLine('-', y + height - 1, x + 1, x + width - 1); + + this.drawVLine('|', x, y + 1, y + height - 1); + this.drawVLine('|', x + width - 1, y + 1, y + height - 1); + + this.drawChar(',', x, y); + this.drawChar('.', x + width - 1, y); + this.drawChar('`', x, y + height - 1); + this.drawChar('\'', x + width - 1, y + height - 1); + } + + public void drawBoxSimpleUnicode(int x, int y, int width, int height) { + this.drawHLine('\u2500', y, x + 1, x + width - 1); + this.drawHLine('\u2500', y + height - 1, x + 1, x + width - 1); + + this.drawVLine('\u2502', x, y + 1, y + height - 1); + this.drawVLine('\u2502', x + width - 1, y + 1, y + height - 1); + + this.drawChar('\u250c', x, y); + this.drawChar('\u2510', x + width - 1, y); + this.drawChar('\u2514', x, y + height - 1); + this.drawChar('\u2518', x + width - 1, y + height - 1); + } + + public void drawStickMan(int x, int y) { + this.drawStringLR(",-.", x, y++); + this.drawStringLR("`-'", x, y++); + this.drawStringLR("/|\\", x, y++); + this.drawStringLR(" | ", x, y++); + this.drawStringLR("/ \\", x, y++); + } + + public void drawStickManUnicode(int x, int y) { + this.drawStringLR("\u250c\u2500\u2510", x, y++); + this.drawStringLR("\u2551\"\u2502", x, y++); + this.drawStringLR("\u2514\u252c\u2518", x, y++); + this.drawStringLR("\u250c\u253c\u2510", x, y++); + this.drawStringLR(" \u2502 ", x, y++); + this.drawStringLR("\u250c\u2534\u2510", x, y++); + } + + public void drawStringsLR(Collection strings, int x, int y) { + int i = 0; + for (CharSequence s : strings) { + this.drawStringLR(s.toString(), x, y + i); + i++; + } + + } + + public void drawNoteSimple(int x, int y, int width, int height) { + this.drawHLine('-', y, x + 1, x + width - 1); + this.drawHLine('-', y + height - 1, x + 1, x + width - 1); + + this.drawVLine('|', x, y + 1, y + height - 1); + this.drawVLine('|', x + width - 1, y + 1, y + height - 1); + + this.drawChar(',', x, y); + + this.drawStringLR("!. ", x + width - 3, y); + this.drawStringLR("|_\\", x + width - 3, y + 1); + + this.drawChar('`', x, y + height - 1); + this.drawChar('\'', x + width - 1, y + height - 1); + } + + public void drawNoteSimpleUnicode(int x, int y, int width, int height) { + this.drawChar('\u2591', x + width - 2, y + 1); + + this.drawHLine('\u2550', y, x + 1, x + width - 1, '\u2502', '\u2567'); + this.drawHLine('\u2550', y + height - 1, x + 1, x + width - 1, '\u2502', '\u2564'); + + this.drawVLine('\u2551', x, y + 1, y + height - 1); + this.drawVLine('\u2551', x + width - 1, y + 1, y + height - 1); + + this.drawChar('\u2554', x, y); + this.drawChar('\u2557', x + width - 1, y); + this.drawChar('\u255a', x, y + height - 1); + this.drawChar('\u255d', x + width - 1, y + height - 1); + } +} diff --git a/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java b/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java new file mode 100644 index 000000000..7554bc8ae --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/AbstractEntityDiagram.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5350 $ + * + */ +package net.sourceforge.plantuml.classdiagram; + +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public abstract class AbstractEntityDiagram extends CucaDiagram { + + abstract public IEntity getOrCreateClass(String code); + + final protected List getDotStrings() { +// return Arrays.asList("nodesep=.5;", "ranksep=0.8;", "edge [fontsize=11,labelfontsize=11];", +// "node [fontsize=11,height=.35,width=.55];"); + return Arrays.asList("nodesep=.35;", "ranksep=0.8;", "edge [fontsize=11,labelfontsize=11];", + "node [fontsize=11,height=.35,width=.55];"); + } + + final public String getDescription() { + return "(" + entities().size() + " entities)"; + } + + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java new file mode 100644 index 000000000..a14e5b817 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java @@ -0,0 +1,148 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5536 $ + * + */ +package net.sourceforge.plantuml.classdiagram; + +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; + +public class ClassDiagram extends AbstractClassOrObjectDiagram { + + @Override + public IEntity getOrCreateEntity(String code, EntityType defaultType) { + assert defaultType == EntityType.ABSTRACT_CLASS || defaultType == EntityType.CLASS + || defaultType == EntityType.INTERFACE || defaultType == EntityType.ENUM + || defaultType == EntityType.LOLLIPOP; + code = getFullyQualifiedCode(code); + if (super.entityExist(code)) { + return super.getOrCreateEntity(code, defaultType); + } + return createEntityWithNamespace(code, getShortName(code), defaultType); + } + + @Override + public Entity createEntity(String code, String display, EntityType type) { + if (type != EntityType.ABSTRACT_CLASS && type != EntityType.CLASS && type != EntityType.INTERFACE + && type != EntityType.ENUM && type != EntityType.LOLLIPOP) { + return super.createEntity(code, display, type); + } + code = getFullyQualifiedCode(code); + if (super.entityExist(code)) { + throw new IllegalArgumentException("Already known: " + code); + } + return createEntityWithNamespace(code, display, type); + } + + private Entity createEntityWithNamespace(String fullyCode, String display, EntityType type) { + Group group = getCurrentGroup(); + final String namespace = getNamespace(fullyCode); + if (namespace != null && (group == null || group.getCode().equals(namespace) == false)) { + group = getOrCreateGroupInternal(namespace, namespace, namespace, GroupType.PACKAGE, null); + group.setBold(true); + } + return createEntityInternal(fullyCode, display == null ? getShortName(fullyCode) : display, type, group); + } + + @Override + public final boolean entityExist(String code) { + return super.entityExist(getFullyQualifiedCode(code)); + } + + @Override + public IEntity getOrCreateClass(String code) { + return getOrCreateEntity(code, EntityType.CLASS); + } + + final public IEntity getOrCreateClass(String code, EntityType type) { + if (type != EntityType.ABSTRACT_CLASS && type != EntityType.CLASS && type != EntityType.INTERFACE + && type != EntityType.ENUM && type != EntityType.LOLLIPOP) { + throw new IllegalArgumentException(); + } + return getOrCreateEntity(code, type); + } + + private String getFullyQualifiedCode(String code) { + if (code.startsWith("\\") || code.startsWith("~") || code.startsWith(".")) { + return code.substring(1); + } + if (code.contains(".")) { + return code; + } + final Group g = this.getCurrentGroup(); + if (g == null) { + return code; + } + final String namespace = g.getNamespace(); + if (namespace == null) { + return code; + } + return namespace + "." + code; + } + + private String getShortName(String code) { + // final int x = code.lastIndexOf('.'); + // if (x == -1) { + // return code; + // } + // return code.substring(x + 1); + final String namespace = getNamespace(code); + if (namespace == null) { + return code; + } + return code.substring(namespace.length() + 1); + } + + private String getNamespace(String code) { + assert code.startsWith("\\") == false; + assert code.startsWith("~") == false; + do { + final int x = code.lastIndexOf('.'); + if (x == -1) { + return null; + } + code = code.substring(0, x); + } while (entityExist(code)); + return code; + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.CLASS; + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java new file mode 100644 index 000000000..8bec4b36f --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5472 $ + * + */ +package net.sourceforge.plantuml.classdiagram; + +import net.sourceforge.plantuml.classdiagram.command.CommandAddMethod; +import net.sourceforge.plantuml.classdiagram.command.CommandCreateEntityClass; +import net.sourceforge.plantuml.classdiagram.command.CommandCreateEntityClassMultilines; +import net.sourceforge.plantuml.classdiagram.command.CommandEndNamespace; +import net.sourceforge.plantuml.classdiagram.command.CommandHideShow; +import net.sourceforge.plantuml.classdiagram.command.CommandImport; +import net.sourceforge.plantuml.classdiagram.command.CommandLinkClass2; +import net.sourceforge.plantuml.classdiagram.command.CommandLinkLollipop; +import net.sourceforge.plantuml.classdiagram.command.CommandMultilinesClassNote; +import net.sourceforge.plantuml.classdiagram.command.CommandNamespace; +import net.sourceforge.plantuml.classdiagram.command.CommandStereotype; +import net.sourceforge.plantuml.classdiagram.command.CommandUrl; +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.command.CommandCreateNote; +import net.sourceforge.plantuml.command.CommandEndPackage; +import net.sourceforge.plantuml.command.CommandMultilinesStandaloneNote; +import net.sourceforge.plantuml.command.CommandNoteEntity; +import net.sourceforge.plantuml.command.CommandPackage; +import net.sourceforge.plantuml.command.CommandPage; + +public class ClassDiagramFactory extends AbstractUmlSystemCommandFactory { + + private ClassDiagram system; + + public ClassDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new ClassDiagram(); + + addCommonCommands(system); + + addCommand(new CommandPage(system)); + addCommand(new CommandAddMethod(system)); + + addCommand(new CommandCreateEntityClass(system)); + addCommand(new CommandCreateNote(system)); + + addCommand(new CommandPackage(system)); + addCommand(new CommandEndPackage(system)); + addCommand(new CommandNamespace(system)); + addCommand(new CommandEndNamespace(system)); + addCommand(new CommandStereotype(system)); + + //addCommand(new CommandLinkClass(system)); + addCommand(new CommandLinkClass2(system)); + addCommand(new CommandLinkLollipop(system)); + + addCommand(new CommandImport(system)); + addCommand(new CommandNoteEntity(system)); + addCommand(new CommandUrl(system)); + + addCommand(new CommandMultilinesClassNote(system)); + addCommand(new CommandMultilinesStandaloneNote(system)); + addCommand(new CommandCreateEntityClassMultilines(system)); + + addCommand(new CommandHideShow(system)); + + } +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java new file mode 100644 index 000000000..6dc02c55a --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.skin.VisibilityModifier; + +public class CommandAddMethod extends SingleLineCommand { + + public CommandAddMethod(ClassDiagram diagram) { + super(diagram, "(?i)^([\\p{L}0-9_.]+)\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Entity entity = (Entity) getSystem().getOrCreateClass(arg.get(0)); + + final String field = arg.get(1); + if (field.length() > 0 && VisibilityModifier.isVisibilityCharacter(field.charAt(0))) { + getSystem().setVisibilityModifierPresent(true); + } + entity.addFieldOrMethod(field); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass.java new file mode 100644 index 000000000..cc21ca9d7 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5075 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandCreateEntityClass extends SingleLineCommand { + + public CommandCreateEntityClass(ClassDiagram diagram) { + super( + diagram, + "(?i)^(interface|enum|abstract\\s+class|abstract|class)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String arg0 = arg.get(0).toUpperCase(); + final EntityType type = EntityType.getEntityType(arg0); + final String code = arg.get(2); + final String display = arg.get(1); + final String stereotype = arg.get(3); + final Entity entity; + if (getSystem().entityExist(code)) { + // return CommandExecutionResult.error("Class already exists : " + // + code); + entity = (Entity) getSystem().getOrCreateEntity(code, type); + entity.muteToType(type); + } else { + entity = getSystem().createEntity(code, display, type); + } + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines.java new file mode 100644 index 000000000..687b74a06 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4161 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.skin.VisibilityModifier; + +public class CommandCreateEntityClassMultilines extends CommandMultilines { + + public CommandCreateEntityClassMultilines(ClassDiagram diagram) { + super( + diagram, + "(?i)^(interface|enum|abstract\\s+class|abstract|class)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?\\s*\\{\\s*$", + "(?i)^\\s*\\}\\s*$"); + } + + public CommandExecutionResult execute(List lines) { + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final Entity entity = executeArg0(line0); + if (entity == null) { + return CommandExecutionResult.error("No such entity"); + } + for (String s : lines.subList(1, lines.size() - 1)) { + if (s.length() > 0 && VisibilityModifier.isVisibilityCharacter(s.charAt(0))) { + getSystem().setVisibilityModifierPresent(true); + } + entity.addFieldOrMethod(s); + } + return CommandExecutionResult.ok(); + } + + private Entity executeArg0(List arg) { + final String arg0 = arg.get(0).toUpperCase(); + final EntityType type = EntityType.getEntityType(arg0); + final String code = arg.get(2); + final String display = arg.get(1); + final String stereotype = arg.get(3); + if (getSystem().entityExist(code)) { + final Entity result = (Entity) getSystem().getOrCreateClass(code); + result.muteToType(type); + return result; + } + final Entity entity = getSystem().createEntity(code, display, type); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return entity; + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandEndNamespace.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandEndNamespace.java new file mode 100644 index 000000000..2ce5b13cd --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandEndNamespace.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; + +public class CommandEndNamespace extends SingleLineCommand { + + public CommandEndNamespace(ClassDiagram diagram) { + super(diagram, "(?i)^end ?namespace$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + if (currentPackage == null) { + return CommandExecutionResult.error("No namesspace defined"); + } + getSystem().endGroup(); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow.java new file mode 100644 index 000000000..c280155eb --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShow.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.EntityGender; +import net.sourceforge.plantuml.cucadiagram.EntityGenderUtils; +import net.sourceforge.plantuml.cucadiagram.EntityPortion; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class CommandHideShow extends SingleLineCommand { + + private static final EnumSet PORTION_METHOD = EnumSet. of(EntityPortion.METHOD); + private static final EnumSet PORTION_MEMBER = EnumSet. of(EntityPortion.FIELD, + EntityPortion.METHOD); + private static final EnumSet PORTION_FIELD = EnumSet. of(EntityPortion.FIELD); + + public CommandHideShow(ClassDiagram classDiagram) { + super( + classDiagram, + "(?i)^(hide|show)\\s+(?:(class|interface|enum|abstract|[\\p{L}0-9_.]+|\\<\\<.*\\>\\>)\\s+)*?(?:(empty)\\s+)?(members?|attributes?|fields?|methods?|circle\\w*|stereotypes?)$"); + } + + private final EntityGender emptyByGender(Set portion) { + if (portion == PORTION_METHOD) { + return EntityGenderUtils.emptyMethods(); + } + if (portion == PORTION_FIELD) { + return EntityGenderUtils.emptyFields(); + } + if (portion == PORTION_MEMBER) { + return EntityGenderUtils.emptyMembers(); + } + return EntityGenderUtils.all(); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Set portion = getEntityPortion(arg.get(3)); + EntityGender gender = null; + + if (arg.get(1) == null) { + gender = EntityGenderUtils.all(); + } else if (arg.get(1).equalsIgnoreCase("class")) { + gender = EntityGenderUtils.byEntityType(EntityType.CLASS); + } else if (arg.get(1).equalsIgnoreCase("interface")) { + gender = EntityGenderUtils.byEntityType(EntityType.INTERFACE); + } else if (arg.get(1).equalsIgnoreCase("enum")) { + gender = EntityGenderUtils.byEntityType(EntityType.ENUM); + } else if (arg.get(1).equalsIgnoreCase("abstract")) { + gender = EntityGenderUtils.byEntityType(EntityType.ABSTRACT_CLASS); + } else if (arg.get(1).startsWith("<<")) { + gender = EntityGenderUtils.byStereotype(arg.get(1)); + } else { + final IEntity entity = getSystem().getOrCreateClass(arg.get(1)); + gender = EntityGenderUtils.byEntityAlone(entity); + } + if (gender != null) { + final boolean empty = arg.get(2) != null; + if (empty == true) { + gender = EntityGenderUtils.and(gender, emptyByGender(portion)); + } + if (getSystem().getCurrentGroup() != null) { + gender = EntityGenderUtils.and(gender, EntityGenderUtils.byPackage(getSystem().getCurrentGroup())); + } + getSystem().hideOrShow(gender, portion, arg.get(0).equalsIgnoreCase("show")); + } + return CommandExecutionResult.ok(); + } + + private Set getEntityPortion(String s) { + final String sub = s.substring(0, 3).toLowerCase(); + if (sub.equals("met")) { + return PORTION_METHOD; + } + if (sub.equals("mem")) { + return PORTION_MEMBER; + } + if (sub.equals("att") || sub.equals("fie")) { + return PORTION_FIELD; + } + if (sub.equals("cir")) { + return EnumSet. of(EntityPortion.CIRCLED_CHARACTER); + } + if (sub.equals("ste")) { + return EnumSet. of(EntityPortion.STEREOTYPE); + } + throw new IllegalArgumentException(); + } +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandImport.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandImport.java new file mode 100644 index 000000000..23b285e26 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandImport.java @@ -0,0 +1,110 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import net.sourceforge.plantuml.FileSystem; +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandImport extends SingleLineCommand { + + public CommandImport(ClassDiagram classDiagram) { + super(classDiagram, "(?i)^import\\s+\"?([^\"]+)\"?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String arg0 = arg.get(0); + try { + final File f = FileSystem.getInstance().getFile(arg0); + + if (f.isFile()) { + includeSimpleFile(f); + } else if (f.isDirectory()) { + includeDirectory(f); + } + } catch (IOException e) { + e.printStackTrace(); + return CommandExecutionResult.error("IO error " + e); + } + return CommandExecutionResult.ok(); + } + + private void includeDirectory(File dir) throws IOException { + for (File f : dir.listFiles()) { + includeSimpleFile(f); + } + + } + + private void includeSimpleFile(File f) throws IOException { + if (f.getName().toLowerCase().endsWith(".java")) { + includeFileJava(f); + } + // if (f.getName().toLowerCase().endsWith(".sql")) { + // includeFileSql(f); + // } + } + + private void includeFileJava(final File f) throws IOException { + final JavaFile javaFile = new JavaFile(f); + for (JavaClass cl : javaFile.getJavaClasses()) { + final String name = cl.getName(); + final IEntity ent1 = getSystem() + .getOrCreateClass(name, cl.getType()); + + for (String p : cl.getParents()) { + final IEntity ent2 = getSystem().getOrCreateClass(p, + cl.getParentType()); + final Link link = new Link(ent2, ent1, new LinkType( + LinkDecor.NONE, LinkDecor.EXTENDS), null, 2); + getSystem().addLink(link); + } + } + } + + // private void includeFileSql(final File f) throws IOException { + // new SqlImporter(getSystem(), f).process(); + // } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java new file mode 100644 index 000000000..7ca74a364 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -0,0 +1,418 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5436 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; + +final public class CommandLinkClass extends SingleLineCommand { + + private static final int OFFSET = 1; + + private static final int FIRST_TYPE_AND_CLASS = 0 + OFFSET; + private static final int FIRST_TYPE = 1 + OFFSET; + private static final int FIRST_CLASS = 2 + OFFSET; + private static final int FIRST_LABEL = 3 + OFFSET; + private static final int LEFT_TO_RIGHT = 4 + OFFSET; + private static final int LEFT_TO_RIGHT_QUEUE = 5 + OFFSET; + private static final int LEFT_TO_RIGHT_HEAD = 6 + OFFSET; + private static final int RIGHT_TO_LEFT = 7 + OFFSET; + private static final int RIGHT_TO_LEFT_HEAD = 8 + OFFSET; + private static final int RIGHT_TO_LEFT_QUEUE = 9 + OFFSET; + private static final int NAV_AGREG_OR_COMPO_INV = 10 + OFFSET; + private static final int NAV_AGREG_OR_COMPO_INV_QUEUE = 11 + OFFSET; + private static final int NAV_AGREG_OR_COMPO_INV_HEAD = 12 + OFFSET; + private static final int NAV_AGREG_OR_COMPO = 13 + OFFSET; + private static final int NAV_AGREG_OR_COMPO_HEAD = 14 + OFFSET; + private static final int NAV_AGREG_OR_COMPO_QUEUE = 15 + OFFSET; + private static final int SECOND_LABEL = 16 + OFFSET; + private static final int SECOND_TYPE_AND_CLASS = 17 + OFFSET; + private static final int SECOND_TYPE = 18 + OFFSET; + private static final int SECOND_CLASS = 19 + OFFSET; + private static final int LINK_LABEL = 20 + OFFSET; + + private final Pattern patternAssociationPoint = Pattern + .compile("\\(\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*,\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*\\)"); + + // [\\p{L}0-9_.]+ + // \\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)* + + public CommandLinkClass(AbstractClassOrObjectDiagram diagram) { + super( + diagram, + "(?i)^(?:@(\\d+)\\s+)?((?:" + + optionalKeywords(diagram.getUmlDiagramType()) + + "\\s+)?" + + "(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)|\\(\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*,\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*\\)" + + ")\\s*(?:\"([^\"]+)\")?\\s*" + // split here + + "(?:" + + "(([-=.]+(?:left|right|up|down|le?|ri?|up?|do?)?[-=.]*)(o +|[\\]>*+]|\\|[>\\]])?)" + + "|" + + "(( +o|[\\[<*+]|[<\\[]\\|)?([-=.]*(?:left|right|up|down|le?|ri?|up?|do?)?[-=.]+))" + + "|" + + "(\\<([-=.]*(?:left|right|up|down|le?|ri?|up?|do?[-=.]+)?[-=.]+)(o +|\\*))" + + "|" + + "(( +o|\\*)([-=.]+(?:left|right|up|down|le?|ri?|up?|do?)?[-=.]*)\\>)" + + ")" + // split here + + "\\s*(?:\"([^\"]+)\")?\\s*((?:" + + optionalKeywords(diagram.getUmlDiagramType()) + + "\\s+)?" + + "(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)|\\(\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*,\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*\\)" + + ")\\s*(?::\\s*([^\"]+))?$"); + // "(?i)^(?:@(\\d+)\\s+)?((?:(interface|enum|abstract\\s+class|abstract|class)\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)|\\(\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*,\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*\\))\\s*(?:\"([^\"]+)\")?\\s*" + // + + // "(?:(([-=.]+)([\\]>o*+]|\\|[>\\]])?)|(([\\[))" + // + + // "\\s*(?:\"([^\"]+)\")?\\s*((?:(interface|enum|abstract\\s+class|abstract|class)\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)|\\(\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*,\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*\\))\\s*(?::\\s*([^\"]+))?$"); + } + + private static String optionalKeywords(UmlDiagramType type) { + if (type == UmlDiagramType.CLASS) { + return "(interface|enum|abstract\\s+class|abstract|class)"; + } + if (type == UmlDiagramType.OBJECT) { + return "(object)"; + } + throw new IllegalArgumentException(); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (arg.get(FIRST_TYPE_AND_CLASS).startsWith("(")) { + return executeArgSpecial1(arg); + } + if (arg.get(SECOND_TYPE_AND_CLASS).startsWith("(")) { + return executeArgSpecial2(arg); + } + if (getSystem().isGroup(arg.get(FIRST_CLASS)) && getSystem().isGroup(arg.get(SECOND_CLASS))) { + return executePackageLink(arg); + } + if (getSystem().isGroup(arg.get(FIRST_CLASS)) || getSystem().isGroup(arg.get(SECOND_CLASS))) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final Entity cl1 = (Entity) getSystem().getOrCreateClass(arg.get(FIRST_CLASS)); + final Entity cl2 = (Entity) getSystem().getOrCreateClass(arg.get(SECOND_CLASS)); + + if (arg.get(FIRST_TYPE) != null) { + final EntityType type = EntityType.getEntityType(arg.get(FIRST_TYPE)); + if (type != EntityType.OBJECT) { + cl1.muteToType(type); + } + } + if (arg.get(SECOND_TYPE) != null) { + final EntityType type = EntityType.getEntityType(arg.get(SECOND_TYPE)); + if (type != EntityType.OBJECT) { + cl2.muteToType(type); + } + } + + final LinkType linkType = getLinkType(arg); + final String queueRaw = getQueue(arg); + final String queue = StringUtils.manageQueueForCuca(queueRaw); + + Link link = new Link(cl1, cl2, linkType, arg.get(LINK_LABEL), queue.length(), arg.get(FIRST_LABEL), arg + .get(SECOND_LABEL), getSystem().getLabeldistance(), getSystem().getLabelangle()); + + if (queueRaw.matches(".*\\w.*")) { + if (arg.get(LEFT_TO_RIGHT) != null) { + Direction direction = StringUtils.getQueueDirection(arg.get(LEFT_TO_RIGHT_QUEUE)); + if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + direction = direction.getInv(); + } + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + } + if (arg.get(RIGHT_TO_LEFT) != null) { + Direction direction = StringUtils.getQueueDirection(arg.get(RIGHT_TO_LEFT_QUEUE)); + if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + direction = direction.getInv(); + } + if (direction == Direction.RIGHT || direction == Direction.DOWN) { + link = link.getInv(); + } + } + if (arg.get(NAV_AGREG_OR_COMPO) != null) { + Direction direction = StringUtils.getQueueDirection(arg.get(NAV_AGREG_OR_COMPO_QUEUE)); + if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + direction = direction.getInv(); + } + if (direction == Direction.RIGHT || direction == Direction.DOWN) { + link = link.getInv(); + } + } + if (arg.get(NAV_AGREG_OR_COMPO_INV) != null) { + Direction direction = StringUtils.getQueueDirection(arg.get(NAV_AGREG_OR_COMPO_INV_QUEUE)); + if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + direction = direction.getInv(); + } + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + } + } + + getSystem().resetPragmaLabel(); + addLink(link, arg.get(0)); + + return CommandExecutionResult.ok(); + } + + private void addLink(Link link, String arg0) { + getSystem().addLink(link); + if (arg0 == null) { + final LinkType type = link.getType(); + // --|> highest + // --*, -->, --o normal + // ..*, ..>, ..o lowest + // if (type.isDashed() == false) { + // if (type.contains(LinkDecor.EXTENDS)) { + // link.setWeight(3); + // } + // if (type.contains(LinkDecor.ARROW) || + // type.contains(LinkDecor.COMPOSITION) + // || type.contains(LinkDecor.AGREGATION)) { + // link.setWeight(2); + // } + // } + } else { + link.setWeight(Integer.parseInt(arg0)); + } + } + + private CommandExecutionResult executePackageLink(List arg) { + final Group cl1 = getSystem().getGroup(arg.get(FIRST_CLASS)); + final Group cl2 = getSystem().getGroup(arg.get(SECOND_CLASS)); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get(LINK_LABEL), queue + .length(), arg.get(FIRST_LABEL), arg.get(SECOND_LABEL), getSystem().getLabeldistance(), getSystem() + .getLabelangle()); + getSystem().resetPragmaLabel(); + addLink(link, arg.get(0)); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeArgSpecial1(List arg) { + final Matcher m = patternAssociationPoint.matcher(arg.get(FIRST_TYPE_AND_CLASS)); + if (m.matches() == false) { + throw new IllegalStateException(); + } + final String clName1 = m.group(1); + final String clName2 = m.group(2); + if (getSystem().entityExist(clName1) == false) { + return CommandExecutionResult.error("No class " + clName1); + } + if (getSystem().entityExist(clName2) == false) { + return CommandExecutionResult.error("No class " + clName2); + } + final IEntity entity1 = getSystem().getOrCreateClass(clName1); + final IEntity entity2 = getSystem().getOrCreateClass(clName2); + + final Entity node = getSystem().createEntity(arg.get(FIRST_TYPE_AND_CLASS), "node", + EntityType.POINT_FOR_ASSOCIATION); + + getSystem().insertBetween(entity1, entity2, node); + final IEntity cl2 = getSystem().getOrCreateClass(arg.get(SECOND_CLASS)); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(node, cl2, linkType, arg.get(LINK_LABEL), queue.length()); + addLink(link, arg.get(0)); + + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeArgSpecial2(List arg) { + final Matcher m = patternAssociationPoint.matcher(arg.get(SECOND_TYPE_AND_CLASS)); + if (m.matches() == false) { + throw new IllegalStateException(); + } + final String clName1 = m.group(1); + final String clName2 = m.group(2); + if (getSystem().entityExist(clName1) == false) { + return CommandExecutionResult.error("No class " + clName1); + } + if (getSystem().entityExist(clName2) == false) { + return CommandExecutionResult.error("No class " + clName2); + } + final IEntity entity1 = getSystem().getOrCreateClass(clName1); + final IEntity entity2 = getSystem().getOrCreateClass(clName2); + + final IEntity node = getSystem().createEntity(arg.get(SECOND_TYPE_AND_CLASS), "node", + EntityType.POINT_FOR_ASSOCIATION); + + getSystem().insertBetween(entity1, entity2, node); + final IEntity cl1 = getSystem().getOrCreateClass(arg.get(FIRST_TYPE_AND_CLASS)); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(cl1, node, linkType, arg.get(LINK_LABEL), queue.length()); + addLink(link, arg.get(0)); + + return CommandExecutionResult.ok(); + } + + private LinkType getLinkTypeNormal(List arg) { + final String queue = arg.get(LEFT_TO_RIGHT_QUEUE).trim(); + String key = arg.get(LEFT_TO_RIGHT_HEAD); + if (key != null) { + key = key.trim(); + } + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType; + } + + private LinkType getLinkTypeInv(List arg) { + final String queue = arg.get(RIGHT_TO_LEFT_QUEUE).trim(); + String key = arg.get(RIGHT_TO_LEFT_HEAD); + if (key != null) { + key = key.trim(); + } + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType.getInv(); + } + + private LinkType getLinkType(List arg) { + if (arg.get(LEFT_TO_RIGHT) != null) { + return getLinkTypeNormal(arg); + } + if (arg.get(RIGHT_TO_LEFT) != null) { + return getLinkTypeInv(arg); + } + if (arg.get(NAV_AGREG_OR_COMPO_INV) != null) { + final String type = arg.get(NAV_AGREG_OR_COMPO_INV_HEAD).trim(); + final String queue = arg.get(NAV_AGREG_OR_COMPO_INV_QUEUE).trim(); + LinkType result; + if (type.equals("*")) { + result = new LinkType(LinkDecor.COMPOSITION, LinkDecor.ARROW); + } else if (type.equals("o")) { + result = new LinkType(LinkDecor.AGREGATION, LinkDecor.ARROW); + } else { + throw new IllegalArgumentException(); + } + if (queue.startsWith(".")) { + result = result.getDashed(); + } + return result; + } + if (arg.get(NAV_AGREG_OR_COMPO) != null) { + final String type = arg.get(NAV_AGREG_OR_COMPO_HEAD).trim(); + final String queue = arg.get(NAV_AGREG_OR_COMPO_QUEUE).trim(); + LinkType result; + if (type.equals("*")) { + result = new LinkType(LinkDecor.ARROW, LinkDecor.COMPOSITION); + } else if (type.equals("o")) { + result = new LinkType(LinkDecor.ARROW, LinkDecor.AGREGATION); + } else { + throw new IllegalArgumentException(); + } + if (queue.startsWith(".")) { + result = result.getDashed(); + } + return result; + } + throw new IllegalArgumentException(); + } + + private String getQueue(List arg) { + if (arg.get(LEFT_TO_RIGHT) != null) { + return arg.get(LEFT_TO_RIGHT_QUEUE).trim(); + } + if (arg.get(RIGHT_TO_LEFT) != null) { + return arg.get(RIGHT_TO_LEFT_QUEUE).trim(); + } + if (arg.get(NAV_AGREG_OR_COMPO_INV) != null) { + return arg.get(NAV_AGREG_OR_COMPO_INV_QUEUE).trim(); + } + if (arg.get(NAV_AGREG_OR_COMPO) != null) { + return arg.get(NAV_AGREG_OR_COMPO_QUEUE).trim(); + } + throw new IllegalArgumentException(); + } + + private LinkType getLinkTypeFromKey(String k) { + if (k == null) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + if (k.equals("+")) { + return new LinkType(LinkDecor.PLUS, LinkDecor.NONE); + } + if (k.equals("*")) { + return new LinkType(LinkDecor.COMPOSITION, LinkDecor.NONE); + } + if (k.equalsIgnoreCase("o")) { + return new LinkType(LinkDecor.AGREGATION, LinkDecor.NONE); + } + if (k.equals("<") || k.equals(">")) { + return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); + } + if (k.equals("<|") || k.equals("|>")) { + return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); + } + // return null; + throw new IllegalArgumentException(k); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass2.java new file mode 100644 index 000000000..2195063a1 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass2.java @@ -0,0 +1,388 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5436 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.Map; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; + +final public class CommandLinkClass2 extends SingleLineCommand2 { + + public CommandLinkClass2(AbstractClassOrObjectDiagram diagram) { + super(diagram, getRegexConcat(diagram.getUmlDiagramType())); + } + + static RegexConcat getRegexConcat(UmlDiagramType umlDiagramType) { + return new RegexConcat( + new RegexLeaf("HEADER", "^(?:@(\\d+)\\s+)?"), + new RegexOr( + new RegexLeaf("ENT1", "(?:" + optionalKeywords(umlDiagramType) + "\\s+)?" + + "(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)"), + new RegexLeaf("COUPLE1", + "\\(\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*,\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*\\)")), + new RegexLeaf("\\s*"), + new RegexLeaf("FIRST_LABEL", "(?:\"([^\"]+)\")?"), + new RegexLeaf("\\s*"), + new RegexOr(new RegexLeaf("LEFT_TO_RIGHT", + "(([-=.]+)(left|right|up|down|le?|ri?|up?|do?)?([-=.]*)(o +|[\\]>*+]|\\|[>\\]])?)"), + new RegexLeaf("RIGHT_TO_LEFT", + "(( +o|[\\[<*+]|[<\\[]\\|)?([-=.]*)(left|right|up|down|le?|ri?|up?|do?)?([-=.]+))"), + new RegexLeaf("NAV_AGREG_OR_COMPO_INV", + "(\\<([-=.]*)(left|right|up|down|le?|ri?|up?|do?[-=.]+)?([-=.]+)(o +|\\*))"), + new RegexLeaf("NAV_AGREG_OR_COMPO", + "(( +o|\\*)([-=.]+)(left|right|up|down|le?|ri?|up?|do?)?([-=.]*)\\>)")), + new RegexLeaf("\\s*"), + new RegexLeaf("SECOND_LABEL", "(?:\"([^\"]+)\")?"), + new RegexLeaf("\\s*"), + new RegexOr( + new RegexLeaf("ENT2", "(?:" + optionalKeywords(umlDiagramType) + "\\s+)?" + + "(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)"), + new RegexLeaf("COUPLE2", + "\\(\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*,\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*\\)")), + new RegexLeaf("\\s*"), new RegexLeaf("LABEL_LINK", "(?::\\s*([^\"]+))?$")); + } + + private static String optionalKeywords(UmlDiagramType type) { + if (type == UmlDiagramType.CLASS) { + return "(interface|enum|abstract\\s+class|abstract|class)"; + } + if (type == UmlDiagramType.OBJECT) { + return "(object)"; + } + throw new IllegalArgumentException(); + } + + @Override + protected CommandExecutionResult executeArg(Map arg) { + final String ent1 = arg.get("ENT1").get(1); + final String ent2 = arg.get("ENT2").get(1); + if (ent1 == null) { + return executeArgSpecial1(arg); + } + if (ent2 == null) { + return executeArgSpecial2(arg); + } + if (getSystem().isGroup(ent1) && getSystem().isGroup(ent2)) { + return executePackageLink(arg); + } + if (getSystem().isGroup(ent1) || getSystem().isGroup(ent2)) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final Entity cl1 = (Entity) getSystem().getOrCreateClass(ent1); + final Entity cl2 = (Entity) getSystem().getOrCreateClass(ent2); + + if (arg.get("ENT1").get(0) != null) { + final EntityType type = EntityType.getEntityType(arg.get("ENT1").get(0)); + if (type != EntityType.OBJECT) { + cl1.muteToType(type); + } + } + if (arg.get("ENT2").get(0) != null) { + final EntityType type = EntityType.getEntityType(arg.get("ENT2").get(0)); + if (type != EntityType.OBJECT) { + cl2.muteToType(type); + } + } + + final LinkType linkType = getLinkType(arg); + Direction dir = getDirection(arg); + final String queue; + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + queue = "-"; + } else { + queue = getQueue(arg); + } + if (dir != null && linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + dir = dir.getInv(); + } + + Link link = new Link(cl1, cl2, linkType, arg.get("LABEL_LINK").get(0), queue.length(), arg.get("FIRST_LABEL") + .get(0), arg.get("SECOND_LABEL").get(0), getSystem().getLabeldistance(), getSystem().getLabelangle()); + + if (dir == Direction.LEFT || dir == Direction.UP) { + link = link.getInv(); + } + + // getSystem().resetPragmaLabel(); + addLink(link, arg.get("HEADER").get(0)); + + return CommandExecutionResult.ok(); + } + + private void addLink(Link link, String arg0) { + getSystem().addLink(link); + if (arg0 == null) { + final LinkType type = link.getType(); + // --|> highest + // --*, -->, --o normal + // ..*, ..>, ..o lowest + // if (type.isDashed() == false) { + // if (type.contains(LinkDecor.EXTENDS)) { + // link.setWeight(3); + // } + // if (type.contains(LinkDecor.ARROW) || + // type.contains(LinkDecor.COMPOSITION) + // || type.contains(LinkDecor.AGREGATION)) { + // link.setWeight(2); + // } + // } + } else { + link.setWeight(Integer.parseInt(arg0)); + } + } + + private CommandExecutionResult executePackageLink(Map arg) { + final String ent1 = arg.get("ENT1").get(1); + final String ent2 = arg.get("ENT2").get(1); + final Group cl1 = getSystem().getGroup(ent1); + final Group cl2 = getSystem().getGroup(ent2); + + final LinkType linkType = getLinkType(arg); + final Direction dir = getDirection(arg); + final String queue; + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + queue = "-"; + } else { + queue = getQueue(arg); + } + + Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get("LABEL_LINK").get( + 0), queue.length(), arg.get("FIRST_LABEL").get(0), arg.get("SECOND_LABEL").get(0), getSystem() + .getLabeldistance(), getSystem().getLabelangle()); + if (dir == Direction.LEFT || dir == Direction.UP) { + link = link.getInv(); + } + + getSystem().resetPragmaLabel(); + addLink(link, arg.get("HEADER").get(0)); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeArgSpecial1(Map arg) { + final String clName1 = arg.get("COUPLE1").get(0); + final String clName2 = arg.get("COUPLE1").get(1); + if (getSystem().entityExist(clName1) == false) { + return CommandExecutionResult.error("No class " + clName1); + } + if (getSystem().entityExist(clName2) == false) { + return CommandExecutionResult.error("No class " + clName2); + } + final Entity node = createAssociationPoint(clName1, clName2); + + final String ent2 = arg.get("ENT2").get(1); + final IEntity cl2 = getSystem().getOrCreateClass(ent2); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(node, cl2, linkType, arg.get("LABEL_LINK").get(0), queue.length()); + addLink(link, arg.get("HEADER").get(0)); + + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeArgSpecial2(Map arg) { + final String clName1 = arg.get("COUPLE2").get(0); + final String clName2 = arg.get("COUPLE2").get(1); + if (getSystem().entityExist(clName1) == false) { + return CommandExecutionResult.error("No class " + clName1); + } + if (getSystem().entityExist(clName2) == false) { + return CommandExecutionResult.error("No class " + clName2); + } + final Entity node = createAssociationPoint(clName1, clName2); + + final String ent1 = arg.get("ENT1").get(1); + final IEntity cl1 = getSystem().getOrCreateClass(ent1); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(cl1, node, linkType, arg.get("LABEL_LINK").get(0), queue.length()); + addLink(link, arg.get("HEADER").get(0)); + + return CommandExecutionResult.ok(); + } + + private Entity createAssociationPoint(final String clName1, final String clName2) { + final IEntity entity1 = getSystem().getOrCreateClass(clName1); + final IEntity entity2 = getSystem().getOrCreateClass(clName2); + + final Entity node = getSystem().createEntity(clName1 + "," + clName2, "node", EntityType.POINT_FOR_ASSOCIATION); + + getSystem().insertBetween(entity1, entity2, node); + return node; + } + + private LinkType getLinkTypeNormal(RegexPartialMatch regexPartialMatch) { + final String queue = regexPartialMatch.get(1).trim() + regexPartialMatch.get(3).trim(); + final String key = regexPartialMatch.get(4); + return getLinkType(queue, key); + } + + private LinkType getLinkTypeInv(RegexPartialMatch regexPartialMatch) { + final String queue = regexPartialMatch.get(2).trim() + regexPartialMatch.get(4).trim(); + final String key = regexPartialMatch.get(1); + return getLinkType(queue, key).getInv(); + } + + private LinkType getLinkType(String queue, String key) { + if (key != null) { + key = key.trim(); + } + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType; + } + + private LinkType getLinkType(Map arg) { + if (arg.get("LEFT_TO_RIGHT").get(0) != null) { + return getLinkTypeNormal(arg.get("LEFT_TO_RIGHT")); + } + if (arg.get("RIGHT_TO_LEFT").get(0) != null) { + return getLinkTypeInv(arg.get("RIGHT_TO_LEFT")); + } + if (arg.get("NAV_AGREG_OR_COMPO_INV").get(0) != null) { + final String type = arg.get("NAV_AGREG_OR_COMPO_INV").get(4).trim(); + final String queue = arg.get("NAV_AGREG_OR_COMPO_INV").get(1).trim() + + arg.get("NAV_AGREG_OR_COMPO_INV").get(3).trim(); + LinkType result; + if (type.equals("*")) { + result = new LinkType(LinkDecor.COMPOSITION, LinkDecor.ARROW); + } else if (type.equals("o")) { + result = new LinkType(LinkDecor.AGREGATION, LinkDecor.ARROW); + } else { + throw new IllegalArgumentException(); + } + if (queue.startsWith(".")) { + result = result.getDashed(); + } + return result; + } + if (arg.get("NAV_AGREG_OR_COMPO").get(0) != null) { + final String type = arg.get("NAV_AGREG_OR_COMPO").get(1).trim(); + final String queue = arg.get("NAV_AGREG_OR_COMPO").get(2).trim() + + arg.get("NAV_AGREG_OR_COMPO").get(4).trim(); + LinkType result; + if (type.equals("*")) { + result = new LinkType(LinkDecor.ARROW, LinkDecor.COMPOSITION); + } else if (type.equals("o")) { + result = new LinkType(LinkDecor.ARROW, LinkDecor.AGREGATION); + } else { + throw new IllegalArgumentException(); + } + if (queue.startsWith(".")) { + result = result.getDashed(); + } + return result; + } + throw new IllegalArgumentException(); + } + + private String getQueue(Map arg) { + if (arg.get("LEFT_TO_RIGHT").get(1) != null) { + return arg.get("LEFT_TO_RIGHT").get(1).trim() + arg.get("LEFT_TO_RIGHT").get(3).trim(); + } + if (arg.get("RIGHT_TO_LEFT").get(2) != null) { + return arg.get("RIGHT_TO_LEFT").get(2).trim() + arg.get("RIGHT_TO_LEFT").get(4).trim(); + } + if (arg.get("NAV_AGREG_OR_COMPO_INV").get(1) != null) { + return arg.get("NAV_AGREG_OR_COMPO_INV").get(1).trim() + arg.get("NAV_AGREG_OR_COMPO_INV").get(3).trim(); + } + if (arg.get("NAV_AGREG_OR_COMPO").get(2) != null) { + return arg.get("NAV_AGREG_OR_COMPO").get(2).trim() + arg.get("NAV_AGREG_OR_COMPO").get(4).trim(); + } + throw new IllegalArgumentException(); + } + + private Direction getDirection(Map arg) { + if (arg.get("LEFT_TO_RIGHT").get(2) != null) { + return StringUtils.getQueueDirection(arg.get("LEFT_TO_RIGHT").get(2)); + } + if (arg.get("RIGHT_TO_LEFT").get(3) != null) { + return StringUtils.getQueueDirection(arg.get("RIGHT_TO_LEFT").get(3)).getInv(); + } + if (arg.get("NAV_AGREG_OR_COMPO").get(3) != null) { + return StringUtils.getQueueDirection(arg.get("NAV_AGREG_OR_COMPO").get(3)).getInv(); + } + if (arg.get("NAV_AGREG_OR_COMPO_INV").get(2) != null) { + return StringUtils.getQueueDirection(arg.get("NAV_AGREG_OR_COMPO_INV").get(2)); + } + return null; + } + + private LinkType getLinkTypeFromKey(String k) { + if (k == null) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + if (k.equals("+")) { + return new LinkType(LinkDecor.PLUS, LinkDecor.NONE); + } + if (k.equals("*")) { + return new LinkType(LinkDecor.COMPOSITION, LinkDecor.NONE); + } + if (k.equalsIgnoreCase("o")) { + return new LinkType(LinkDecor.AGREGATION, LinkDecor.NONE); + } + if (k.equals("<") || k.equals(">")) { + return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); + } + if (k.equals("<|") || k.equals("|>")) { + return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); + } + // return null; + throw new IllegalArgumentException(k); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java new file mode 100644 index 000000000..4d779e0fb --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java @@ -0,0 +1,242 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5075 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; + +final public class CommandLinkLollipop extends SingleLineCommand { + + private static final int OFFSET = 1; + + private static final int FIRST_TYPE_AND_CLASS = 0 + OFFSET; + private static final int FIRST_TYPE = 1 + OFFSET; + private static final int FIRST_CLASS = 2 + OFFSET; + private static final int FIRST_LABEL = 3 + OFFSET; + + private static final int LINK1 = 4 + OFFSET; + private static final int LINK2 = 5 + OFFSET; + + private static final int SECOND_LABEL = 6 + OFFSET; + private static final int SECOND_TYPE_AND_CLASS = 7 + OFFSET; + private static final int SECOND_TYPE = 8 + OFFSET; + private static final int SECOND_CLASS = 9 + OFFSET; + private static final int LINK_LABEL = 10 + OFFSET; + + private final Pattern patternAssociationPoint = Pattern + .compile("\\(\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*,\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*\\)"); + + public CommandLinkLollipop(AbstractClassOrObjectDiagram diagram) { + super( + diagram, + "(?i)^(?:@(\\d+)\\s+)?((?:(interface|enum|abstract\\s+class|abstract|class)\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)|\\(\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*,\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*\\))\\s*(?:\"([^\"]+)\")?\\s*" + // + + // "(?:(([-=.]+)([\\]>o*+]|\\|[>\\]])?)|(([\\[))" + + "(?:\\(\\)([-=.]+)|([-=.]+)\\(\\))" + + "\\s*(?:\"([^\"]+)\")?\\s*((?:(interface|enum|abstract\\s+class|abstract|class)\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)|\\(\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*,\\s*\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*\\s*\\))\\s*(?::\\s*([^\"]+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (arg.get(FIRST_TYPE_AND_CLASS).startsWith("(")) { + return executeArgSpecial1(arg); + } + if (arg.get(SECOND_TYPE_AND_CLASS).startsWith("(")) { + return executeArgSpecial2(arg); + } + if (getSystem().isGroup(arg.get(FIRST_CLASS)) && getSystem().isGroup(arg.get(SECOND_CLASS))) { + return executePackageLink(arg); + } + if (getSystem().isGroup(arg.get(FIRST_CLASS)) || getSystem().isGroup(arg.get(SECOND_CLASS))) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final Entity cl1; + final Entity cl2; + final Entity normalEntity; + + final String suffix = "lol" + UniqueSequence.getValue(); + if (arg.get(LINK1) != null) { + cl2 = (Entity) getSystem().getOrCreateClass(arg.get(SECOND_CLASS)); + cl1 = getSystem().createEntity(cl2.getCode() + suffix, arg.get(FIRST_CLASS), EntityType.LOLLIPOP); + normalEntity = cl2; + } else { + assert arg.get(LINK2) != null; + cl1 = (Entity) getSystem().getOrCreateClass(arg.get(FIRST_CLASS)); + cl2 = getSystem().createEntity(cl1.getCode() + suffix, arg.get(SECOND_CLASS), EntityType.LOLLIPOP); + normalEntity = cl1; + } + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + int length = queue.length(); + if (length == 1 && getSystem().getNbOfHozizontalLollipop(normalEntity) > 1) { + length++; + } + final Link link = new Link(cl1, cl2, linkType, arg.get(LINK_LABEL), length, arg.get(FIRST_LABEL), arg + .get(SECOND_LABEL), getSystem().getLabeldistance(), getSystem().getLabelangle()); + getSystem().resetPragmaLabel(); + addLink(link, arg.get(0)); + + return CommandExecutionResult.ok(); + } + + private String getQueue(List arg) { + if (arg.get(LINK1) != null) { + return arg.get(LINK1); + } + if (arg.get(LINK2) != null) { + return arg.get(LINK2); + } + throw new IllegalArgumentException(); + } + + private LinkType getLinkType(List arg) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + + private void addLink(Link link, String arg0) { + getSystem().addLink(link); + if (arg0 == null) { + final LinkType type = link.getType(); + // --|> highest + // --*, -->, --o normal + // ..*, ..>, ..o lowest + // if (type.isDashed() == false) { + // if (type.contains(LinkDecor.EXTENDS)) { + // link.setWeight(3); + // } + // if (type.contains(LinkDecor.ARROW) || + // type.contains(LinkDecor.COMPOSITION) + // || type.contains(LinkDecor.AGREGATION)) { + // link.setWeight(2); + // } + // } + } else { + link.setWeight(Integer.parseInt(arg0)); + } + } + + private CommandExecutionResult executePackageLink(List arg) { + final Group cl1 = getSystem().getGroup(arg.get(FIRST_CLASS)); + final Group cl2 = getSystem().getGroup(arg.get(SECOND_CLASS)); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get(LINK_LABEL), queue + .length(), arg.get(FIRST_LABEL), arg.get(SECOND_LABEL), getSystem().getLabeldistance(), getSystem() + .getLabelangle()); + getSystem().resetPragmaLabel(); + addLink(link, arg.get(0)); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeArgSpecial1(List arg) { + final Matcher m = patternAssociationPoint.matcher(arg.get(FIRST_TYPE_AND_CLASS)); + if (m.matches() == false) { + throw new IllegalStateException(); + } + final String clName1 = m.group(1); + final String clName2 = m.group(2); + if (getSystem().entityExist(clName1) == false) { + return CommandExecutionResult.error("No class " + clName1); + } + if (getSystem().entityExist(clName2) == false) { + return CommandExecutionResult.error("No class " + clName2); + } + final IEntity entity1 = getSystem().getOrCreateClass(clName1); + final IEntity entity2 = getSystem().getOrCreateClass(clName2); + + final Entity node = getSystem().createEntity(arg.get(FIRST_TYPE_AND_CLASS), "node", + EntityType.POINT_FOR_ASSOCIATION); + + getSystem().insertBetween(entity1, entity2, node); + final IEntity cl2 = getSystem().getOrCreateClass(arg.get(SECOND_CLASS)); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(node, cl2, linkType, arg.get(LINK_LABEL), queue.length()); + addLink(link, arg.get(0)); + + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executeArgSpecial2(List arg) { + final Matcher m = patternAssociationPoint.matcher(arg.get(SECOND_TYPE_AND_CLASS)); + if (m.matches() == false) { + throw new IllegalStateException(); + } + final String clName1 = m.group(1); + final String clName2 = m.group(2); + if (getSystem().entityExist(clName1) == false) { + return CommandExecutionResult.error("No class " + clName1); + } + if (getSystem().entityExist(clName2) == false) { + return CommandExecutionResult.error("No class " + clName2); + } + final IEntity entity1 = getSystem().getOrCreateClass(clName1); + final IEntity entity2 = getSystem().getOrCreateClass(clName2); + + final IEntity node = getSystem().createEntity(arg.get(SECOND_TYPE_AND_CLASS), "node", + EntityType.POINT_FOR_ASSOCIATION); + + getSystem().insertBetween(entity1, entity2, node); + final IEntity cl1 = getSystem().getOrCreateClass(arg.get(FIRST_TYPE_AND_CLASS)); + + final LinkType linkType = getLinkType(arg); + final String queue = getQueue(arg); + + final Link link = new Link(cl1, node, linkType, arg.get(LINK_LABEL), queue.length()); + addLink(link, arg.get(0)); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandMultilinesClassNote.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandMultilinesClassNote.java new file mode 100644 index 000000000..46b09a599 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandMultilinesClassNote.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4239 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.command.AbstractCommandMultilinesNoteEntity; + +public class CommandMultilinesClassNote extends AbstractCommandMultilinesNoteEntity { + + public CommandMultilinesClassNote(final AbstractEntityDiagram system) { + super(system, "(?i)^note\\s+(right|left|top|bottom)\\s+(?:of\\s+)?([\\p{L}0-9_.]+)\\s*(#\\w+)?$"); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandNamespace.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandNamespace.java new file mode 100644 index 000000000..302e446e0 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandNamespace.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3979 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class CommandNamespace extends SingleLineCommand { + + public CommandNamespace(ClassDiagram diagram) { + super(diagram, "(?i)^namespace\\s+([\\p{L}0-9_][\\p{L}0-9_.]*)\\s*(#[0-9a-fA-F]{6}|\\w+)?\\s*\\{?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(0); + final Group currentPackage = getSystem().getCurrentGroup(); + final Group p = getSystem().getOrCreateGroup(code, code, code, GroupType.PACKAGE, currentPackage); + p.setBold(true); + final String color = arg.get(1); + if (color != null) { + p.setBackColor(new HtmlColor(color)); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java new file mode 100644 index 000000000..d1d0cebda --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandStereotype extends SingleLineCommand { + + public CommandStereotype(ClassDiagram classDiagram) { + super(classDiagram, "(?i)^([\\p{L}0-9_.]+)\\s*(\\<\\<.*\\>\\>)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(0); + final String stereotype = arg.get(1); + final Entity entity = (Entity) getSystem().getOrCreateClass(code); + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java new file mode 100644 index 000000000..9cd540468 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4161 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; + +public class CommandUrl extends SingleLineCommand { + + public CommandUrl(ClassDiagram classDiagram) { + super(classDiagram, "(?i)^url\\s*(?:of|for)?\\s+([\\p{L}0-9_.]+)\\s+(?:is)?\\s*\\[\\[(.*)\\]\\]$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(0); + final String url = arg.get(1); + final Entity entity = (Entity) getSystem().getOrCreateClass(code); + entity.setUrl(url); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java b/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java new file mode 100644 index 000000000..f088d9679 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +import net.sourceforge.plantuml.cucadiagram.EntityType; + +class JavaClass { + + private final String name; + private final String javaPackage; + private final List parents = new ArrayList(); + private final EntityType type; + private final EntityType parentType; + + public JavaClass(String javaPackage, String name, String p, EntityType type, EntityType parentType) { + this.name = name; + this.javaPackage = javaPackage; + if (p == null) { + p = ""; + } + final StringTokenizer st = new StringTokenizer(p.trim(), ","); + while (st.hasMoreTokens()) { + this.parents.add(st.nextToken().trim().replaceAll("\\<.*", "")); + } + this.type = type; + this.parentType = parentType; + } + + public final String getName() { + return name; + } + + public final EntityType getType() { + return type; + } + + public final List getParents() { + return Collections.unmodifiableList(parents); + } + + public final EntityType getParentType() { + return parentType; + } + + public final String getJavaPackage() { + return javaPackage; + } + +} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java b/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java new file mode 100644 index 000000000..c0b763247 --- /dev/null +++ b/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java @@ -0,0 +1,108 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.classdiagram.command; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.cucadiagram.EntityType; + +class JavaFile { + + private static final Pattern classDefinition = Pattern + .compile("^(?:public\\s+|abstract\\s+|final\\s+)*(class|interface|enum)\\s+(\\w+)(?:.*\\b(extends|implements)\\s+([\\w\\s,]+))?"); + + private static final Pattern packageDefinition = Pattern.compile("^package\\s+([\\w+.]+)\\s*;"); + + private final List all = new ArrayList(); + + public JavaFile(File f) throws IOException { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(f)); + initFromReader(br); + } finally { + if (br != null) { + br.close(); + } + } + } + + private void initFromReader(BufferedReader br) throws IOException { + String javaPackage = null; + String s; + while ((s = br.readLine()) != null) { + s = s.trim(); + final Matcher matchPackage = packageDefinition.matcher(s); + if (matchPackage.find()) { + javaPackage = matchPackage.group(1); + } else { + final Matcher matchClassDefinition = classDefinition.matcher(s); + if (matchClassDefinition.find()) { + final String n = matchClassDefinition.group(2); + final String p = matchClassDefinition.group(4); + final EntityType type = EntityType.valueOf(matchClassDefinition.group(1).toUpperCase()); + final EntityType parentType = getParentType(type, matchClassDefinition.group(3)); + all.add(new JavaClass(javaPackage, n, p, type, parentType)); + } + } + } + } + + static EntityType getParentType(EntityType type, String extendsOrImplements) { + if (extendsOrImplements == null) { + return null; + } + if (type == EntityType.CLASS) { + if (extendsOrImplements.equals("extends")) { + return EntityType.CLASS; + } + return EntityType.INTERFACE; + } + return EntityType.INTERFACE; + } + + public List getJavaClasses() { + return Collections.unmodifiableList(all); + + } + +} diff --git a/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java new file mode 100644 index 000000000..ced002ccd --- /dev/null +++ b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ArobaseStringCompressor implements StringCompressor { + + private final static Pattern p = Pattern.compile("(?s)(?i)^\\s*(@startuml[^\\n\\r]*)?\\s*(.*?)\\s*(@enduml)?\\s*$"); + + public String compress(String s) throws IOException { + final Matcher m = p.matcher(s); + if (m.find()) { + return m.group(2); + } + return ""; + } + + public String decompress(String stringAnnoted) throws IOException { + return stringAnnoted; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/code/AsciiEncoder.java b/src/net/sourceforge/plantuml/code/AsciiEncoder.java new file mode 100644 index 000000000..c3786bfe4 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/AsciiEncoder.java @@ -0,0 +1,113 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +public class AsciiEncoder implements URLEncoder { + + final private char encode6bit[] = new char[64]; + final private byte decode6bit[] = new byte[128]; + + public AsciiEncoder() { + for (byte b = 0; b < 64; b++) { + encode6bit[b] = encode6bit(b); + decode6bit[encode6bit[b]] = b; + } + } + + public String encode(byte data[]) { + final StringBuilder resu = new StringBuilder((data.length * 4 + 2) / 3); + for (int i = 0; i < data.length; i += 3) { + append3bytes(resu, data[i] & 0xFF, i + 1 < data.length ? data[i + 1] & 0xFF : 0, + i + 2 < data.length ? data[i + 2] & 0xFF : 0); + } + return resu.toString(); + } + + public byte[] decode(String s) { + assert s.length() % 4 == 0 : "Cannot decode " + s; + final byte data[] = new byte[(s.length() * 3 + 3) / 4]; + int pos = 0; + for (int i = 0; i < s.length(); i += 4) { + decode3bytes(data, pos, s.charAt(i), s.charAt(i + 1), s.charAt(i + 2), s.charAt(i + 3)); + pos += 3; + } + return data; + } + + private char encode6bit(byte b) { + assert b >= 0 && b < 64; + if (b < 10) { + return (char) ('0' + b); + } + b -= 10; + if (b < 26) { + return (char) ('A' + b); + } + b -= 26; + if (b < 26) { + return (char) ('a' + b); + } + b -= 26; + if (b == 0) { + return '-'; + } + if (b == 1) { + return '_'; + } + assert false; + return '?'; + } + + private void append3bytes(StringBuilder sb, int b1, int b2, int b3) { + final int c1 = b1 >> 2; + final int c2 = ((b1 & 0x3) << 4) | (b2 >> 4); + final int c3 = ((b2 & 0xF) << 2) | (b3 >> 6); + final int c4 = b3 & 0x3F; + sb.append(encode6bit[c1 & 0x3F]); + sb.append(encode6bit[c2 & 0x3F]); + sb.append(encode6bit[c3 & 0x3F]); + sb.append(encode6bit[c4 & 0x3F]); + } + + private void decode3bytes(byte r[], int pos, char cc1, char cc2, char cc3, char cc4) { + final int c1 = decode6bit[cc1]; + final int c2 = decode6bit[cc2]; + final int c3 = decode6bit[cc3]; + final int c4 = decode6bit[cc4]; + r[pos] = (byte) ((c1 << 2) | (c2 >> 4)); + r[pos + 1] = (byte) (((c2 & 0x0F) << 4) | (c3 >> 2)); + r[pos + 2] = (byte) (((c3 & 0x3) << 6) | c4); + } + +} diff --git a/src/net/sourceforge/plantuml/code/Compression.java b/src/net/sourceforge/plantuml/code/Compression.java new file mode 100644 index 000000000..19e8fc672 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/Compression.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; + +public interface Compression { + + /** + * Shrinks the given in array with length len + * + * @return a newly created array with the compressed data. + */ + byte[] compress(final byte[] in); + + /** + * Grows the given in array with length len + * compressed with the shrink method. + * + * @return a newly created array with the expanded data. + */ + byte[] decompress(byte[] in) throws IOException; + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/code/CompressionGZip.java b/src/net/sourceforge/plantuml/code/CompressionGZip.java new file mode 100644 index 000000000..fc1ec1249 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/CompressionGZip.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class CompressionGZip implements Compression { + + class MyGZIPOutputStream extends GZIPOutputStream { + + public MyGZIPOutputStream(OutputStream baos) throws IOException { + super(baos); + def.setLevel(9); + } + + } + + public byte[] compress(byte[] in) { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + final GZIPOutputStream gz = new MyGZIPOutputStream(baos); + gz.write(in); + gz.close(); + baos.close(); + return baos.toByteArray(); + } catch (IOException e) { + throw new IllegalStateException(e.toString()); + } + } + + public byte[] decompress(byte[] in) throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + final ByteArrayInputStream bais = new ByteArrayInputStream(in); + final GZIPInputStream gz = new GZIPInputStream(bais); + int read; + while ((read = gz.read()) != -1) { + baos.write(read); + } + gz.close(); + bais.close(); + baos.close(); + return baos.toByteArray(); + } + +} diff --git a/src/net/sourceforge/plantuml/code/CompressionHuffman.java b/src/net/sourceforge/plantuml/code/CompressionHuffman.java new file mode 100644 index 000000000..ab78a8e48 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/CompressionHuffman.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +public class CompressionHuffman implements Compression { + + public byte[] compress(byte[] in) { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final Deflater deflater = new Deflater(Deflater.HUFFMAN_ONLY); + deflater.setLevel(9); + final DeflaterOutputStream gz = new DeflaterOutputStream(baos, deflater); + try { + gz.write(in); + gz.close(); + baos.close(); + return baos.toByteArray(); + } catch (IOException e) { + throw new IllegalStateException(e.toString()); + } + } + + public byte[] decompress(byte[] in) throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + final ByteArrayInputStream bais = new ByteArrayInputStream(in); + final InflaterInputStream gz = new InflaterInputStream(bais); + int read; + while ((read = gz.read()) != -1) { + baos.write(read); + } + gz.close(); + bais.close(); + baos.close(); + return baos.toByteArray(); + } + +} diff --git a/src/net/sourceforge/plantuml/code/CompressionNone.java b/src/net/sourceforge/plantuml/code/CompressionNone.java new file mode 100644 index 000000000..93b69e117 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/CompressionNone.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +public class CompressionNone implements Compression { + + public byte[] compress(byte[] in) { + return in; + } + + public byte[] decompress(byte[] in) { + return in; + } + +} diff --git a/src/net/sourceforge/plantuml/code/StringCompressor.java b/src/net/sourceforge/plantuml/code/StringCompressor.java new file mode 100644 index 000000000..4be17abbe --- /dev/null +++ b/src/net/sourceforge/plantuml/code/StringCompressor.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; + +public interface StringCompressor { + + String compress(String s) throws IOException; + + String decompress(String compressed) throws IOException; + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/code/StringCompressorNone.java b/src/net/sourceforge/plantuml/code/StringCompressorNone.java new file mode 100644 index 000000000..79e8fee78 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/StringCompressorNone.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; + +public class StringCompressorNone implements StringCompressor { + + public String compress(String s) throws IOException { + return s; + } + + public String decompress(String stringAnnoted) throws IOException { + return stringAnnoted; + } +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/code/Transcoder.java b/src/net/sourceforge/plantuml/code/Transcoder.java new file mode 100644 index 000000000..07131f074 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/Transcoder.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; + +public class Transcoder { + + private final Compression compression; + private final URLEncoder urlEncoder; + private final StringCompressor stringCompressor; + + public Transcoder() { + this(new AsciiEncoder(), new CompressionHuffman()); + } + + public Transcoder(URLEncoder urlEncoder, Compression compression) { + this(urlEncoder, new ArobaseStringCompressor(), compression); + } + + public Transcoder(URLEncoder urlEncoder, StringCompressor stringCompressor, Compression compression) { + this.compression = compression; + this.urlEncoder = urlEncoder; + this.stringCompressor = stringCompressor; + } + + public String encode(String text) throws IOException { + + final String stringAnnoted = stringCompressor.compress(text); + + final byte[] data = stringAnnoted.getBytes("UTF-8"); + final byte[] compressedData = compression.compress(data); + + return urlEncoder.encode(compressedData); + } + + public String decode(String code) throws IOException { + final byte compressedData[] = urlEncoder.decode(code); + final byte data[] = compression.decompress(compressedData); + + return stringCompressor.decompress(new String(data, "UTF-8")); + } + +} diff --git a/src/net/sourceforge/plantuml/code/URLEncoder.java b/src/net/sourceforge/plantuml/code/URLEncoder.java new file mode 100644 index 000000000..2b7d26563 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/URLEncoder.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +public interface URLEncoder { + + String encode(byte data[]); + + byte[] decode(String s); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java b/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java new file mode 100644 index 000000000..3fb8132fa --- /dev/null +++ b/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public abstract class AbstractCommandMultilinesNoteEntity extends CommandMultilines { + + protected AbstractCommandMultilinesNoteEntity(final AbstractEntityDiagram system, String patternStart) { + super(system, patternStart, "(?i)^end ?note$"); + } + + public final CommandExecutionResult execute(List lines) { + + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final String pos = line0.get(0); + + final IEntity cl1 = getSystem().getOrCreateClass(line0.get(1)); + + final List strings = lines.subList(1, lines.size() - 1); + final String s = StringUtils.getMergedLines(strings); + + final Entity note = getSystem().createEntity("GMN" + UniqueSequence.getValue(), s, EntityType.NOTE); + note.setSpecificBackcolor(line0.get(2)); + + final Position position = Position.valueOf(pos.toUpperCase()).withRankdir(getSystem().getRankdir()); + final Link link; + + final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getDashed(); + if (position == Position.RIGHT) { + link = new Link(cl1, note, type, null, 1); + } else if (position == Position.LEFT) { + link = new Link(note, cl1, type, null, 1); + } else if (position == Position.BOTTOM) { + link = new Link(cl1, note, type, null, 2); + } else if (position == Position.TOP) { + link = new Link(note, cl1, type, null, 2); + } else { + throw new IllegalArgumentException(); + } + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java b/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java new file mode 100644 index 000000000..c102af3b5 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java @@ -0,0 +1,102 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5504 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public abstract class AbstractUmlSystemCommandFactory implements PSystemCommandFactory { + + protected AbstractUmlSystemCommandFactory() { + reset(); + } + + private List cmds = new ArrayList(); + + final public CommandControl isValid(List lines) { + for (Command cmd : cmds) { + final CommandControl result = cmd.isValid(lines); + if (result == CommandControl.OK || result == CommandControl.OK_PARTIAL) { + return result; + } + } + return CommandControl.NOT_OK; + + } + + final public Command createCommand(List lines) { + for (Command cmd : cmds) { + final CommandControl result = cmd.isValid(lines); + if (result == CommandControl.OK) { + return cmd; + } else if (result == CommandControl.OK_PARTIAL) { + throw new IllegalArgumentException(); + } + } + throw new IllegalArgumentException(); + } + + final public void reset() { + cmds = new ArrayList(); + initCommands(); + } + + protected abstract void initCommands(); + + final protected void addCommonCommands(UmlDiagram system) { + addCommand(new CommandPragma(system)); + addCommand(new CommandTitle(system)); + addCommand(new CommandMultilinesTitle(system)); + + addCommand(new CommandFooter(system)); + addCommand(new CommandMultilinesFooter(system)); + + addCommand(new CommandHeader(system)); + addCommand(new CommandMultilinesHeader(system)); + + addCommand(new CommandSkinParam(system)); + addCommand(new CommandMinwidth(system)); + addCommand(new CommandRotate(system)); + addCommand(new CommandScale(system)); + addCommand(new CommandScaleWidthAndHeight(system)); + addCommand(new CommandScaleWidthOrHeight(system)); + } + + protected final void addCommand(Command cmd) { + cmds.add(cmd); + } + +} diff --git a/src/net/sourceforge/plantuml/command/Command.java b/src/net/sourceforge/plantuml/command/Command.java new file mode 100644 index 000000000..1e48903d5 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/Command.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +public interface Command { + + CommandExecutionResult execute(List lines); + + CommandControl isValid(List lines); + + boolean isDeprecated(List lines); + + String getHelpMessageForDeprecated(List lines); + +} diff --git a/src/net/sourceforge/plantuml/command/CommandControl.java b/src/net/sourceforge/plantuml/command/CommandControl.java new file mode 100644 index 000000000..cd795ff7c --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandControl.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.command; + +public enum CommandControl { + OK, NOT_OK, OK_PARTIAL + +} diff --git a/src/net/sourceforge/plantuml/command/CommandCreateNote.java b/src/net/sourceforge/plantuml/command/CommandCreateNote.java new file mode 100644 index 000000000..bd1a43b50 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandCreateNote.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; + +public class CommandCreateNote extends SingleLineCommand { + + public CommandCreateNote(AbstractEntityDiagram diagram) { + super(diagram, "(?i)^note\\s+\"([^\"]+)\"\\s+as\\s+([\\p{L}0-9_.]+)\\s*(#\\w+)?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String display = arg.get(0); + final String code = arg.get(1); + final Entity entity = getSystem().createEntity(code, display, EntityType.NOTE); + assert entity != null; + entity.setSpecificBackcolor(arg.get(2)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandEndPackage.java b/src/net/sourceforge/plantuml/command/CommandEndPackage.java new file mode 100644 index 000000000..37133498f --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandEndPackage.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; + +public class CommandEndPackage extends SingleLineCommand { + + public CommandEndPackage(AbstractEntityDiagram diagram) { + super(diagram, "(?i)^(end ?package|\\})$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + if (currentPackage == null) { + return CommandExecutionResult.error("No package defined"); + } + getSystem().endGroup(); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandExecutionResult.java b/src/net/sourceforge/plantuml/command/CommandExecutionResult.java new file mode 100644 index 000000000..5e2d70a79 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandExecutionResult.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.command; + + +public class CommandExecutionResult { + + private final String error; + + private CommandExecutionResult(String error) { + this.error = error; + } + + public static CommandExecutionResult ok() { + return new CommandExecutionResult(null); + } + + public static CommandExecutionResult error(String error) { + return new CommandExecutionResult(error); + } + + public boolean isOk() { + return error == null; + } + + public String getError() { + if (isOk()) { + throw new IllegalStateException(); + } + return error; + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandFooter.java b/src/net/sourceforge/plantuml/command/CommandFooter.java new file mode 100644 index 000000000..f153e63e8 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandFooter.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; + +public class CommandFooter extends SingleLineCommand { + + public CommandFooter(UmlDiagram diagram) { + super(diagram, "(?i)^(?:(left|right|center)?\\s*)footer(?:\\s*:\\s*|\\s+)(.*[\\p{L}0-9_.].*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String align = arg.get(0); + if (align != null) { + getSystem().setFooterAlignement(HorizontalAlignement.valueOf(align.toUpperCase())); + } + getSystem().setFooter(StringUtils.getWithNewlines(arg.get(1))); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandHeader.java b/src/net/sourceforge/plantuml/command/CommandHeader.java new file mode 100644 index 000000000..dcafe7ee7 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandHeader.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; + +public class CommandHeader extends SingleLineCommand { + + public CommandHeader(UmlDiagram diagram) { + super(diagram, "(?i)^(?:(left|right|center)?\\s*)header(?:\\s*:\\s*|\\s+)(.*[\\p{L}0-9_.].*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String align = arg.get(0); + if (align != null) { + getSystem().setHeaderAlignement(HorizontalAlignement.valueOf(align.toUpperCase())); + } + getSystem().setHeader(StringUtils.getWithNewlines(arg.get(1))); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMinwidth.java b/src/net/sourceforge/plantuml/command/CommandMinwidth.java new file mode 100644 index 000000000..8fd7fe988 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMinwidth.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandMinwidth extends SingleLineCommand { + + public CommandMinwidth(UmlDiagram system) { + super(system, "(?i)^minwidth\\s+(\\d+)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + + final int minwidth = Integer.parseInt(arg.get(0)); + ((UmlDiagram) getSystem()).setMinwidth(minwidth); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines.java b/src/net/sourceforge/plantuml/command/CommandMultilines.java new file mode 100644 index 000000000..9a60656bf --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMultilines.java @@ -0,0 +1,109 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5041 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.PSystem; + +public abstract class CommandMultilines implements Command { + + private final S system; + + private final Pattern starting; + private final Pattern ending; + + public CommandMultilines(final S system, String patternStart, String patternEnd) { + if (patternStart.startsWith("(?i)^") == false || patternStart.endsWith("$") == false) { + throw new IllegalArgumentException("Bad pattern " + patternStart); + } + if (patternEnd.startsWith("(?i)^") == false || patternEnd.endsWith("$") == false) { + throw new IllegalArgumentException("Bad pattern " + patternEnd); + } + this.system = system; + this.starting = Pattern.compile(patternStart); + this.ending = Pattern.compile(patternEnd); + } + + final public CommandControl isValid(List lines) { + if (isCommandForbidden()) { + return CommandControl.NOT_OK; + } + Matcher m1 = starting.matcher(lines.get(0)); + if (m1.matches() == false) { + return CommandControl.NOT_OK; + } + if (lines.size() == 1) { + return CommandControl.OK_PARTIAL; + } + + m1 = ending.matcher(lines.get(lines.size() - 1)); + if (m1.matches() == false) { + return CommandControl.OK_PARTIAL; + } + + actionIfCommandValid(); + return CommandControl.OK; + } + + protected boolean isCommandForbidden() { + return false; + } + + protected void actionIfCommandValid() { + } + + protected S getSystem() { + return system; + } + + protected final Pattern getStartingPattern() { + return starting; + } + + protected final Pattern getEnding() { + return ending; + } + + public boolean isDeprecated(List line) { + return false; + } + + public String getHelpMessageForDeprecated(List lines) { + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java new file mode 100644 index 000000000..f5222067c --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; +import java.util.regex.Matcher; + +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; + +public class CommandMultilinesFooter extends CommandMultilines { + + public CommandMultilinesFooter(final UmlDiagram diagram) { + super(diagram, "(?i)^(?:(left|right|center)?\\s*)footer$", "(?i)^end ?footer$"); + } + + public CommandExecutionResult execute(List lines) { + final Matcher m = getStartingPattern().matcher(lines.get(0)); + if (m.find() == false) { + throw new IllegalStateException(); + } + final String align = m.group(1); + if (align != null) { + getSystem().setFooterAlignement(HorizontalAlignement.valueOf(align.toUpperCase())); + } + final List strings = lines.subList(1, lines.size() - 1); + if (strings.size() > 0) { + getSystem().setFooter(strings); + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("Empty footer"); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java b/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java new file mode 100644 index 000000000..0933d055b --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; +import java.util.regex.Matcher; + +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; + +public class CommandMultilinesHeader extends CommandMultilines { + + public CommandMultilinesHeader(final UmlDiagram diagram) { + super(diagram, "(?i)^(?:(left|right|center)?\\s*)header$", "(?i)^end ?header$"); + } + + public CommandExecutionResult execute(List lines) { + final Matcher m = getStartingPattern().matcher(lines.get(0)); + if (m.find() == false) { + throw new IllegalStateException(); + } + final String align = m.group(1); + if (align != null) { + getSystem().setHeaderAlignement(HorizontalAlignement.valueOf(align.toUpperCase())); + } + final List strings = lines.subList(1, lines.size() - 1); + if (strings.size() > 0) { + getSystem().setHeader(strings); + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("Empty header"); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java b/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java new file mode 100644 index 000000000..8de232104 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.EntityType; + +public class CommandMultilinesStandaloneNote extends CommandMultilines { + + public CommandMultilinesStandaloneNote(final AbstractEntityDiagram system) { + super(system, "(?i)^(note)\\s+as\\s+([\\p{L}0-9_.]+)\\s*(#\\w+)?$", "(?i)^end ?note$"); + } + + public CommandExecutionResult execute(List lines) { + + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + + final List strings = lines.subList(1, lines.size() - 1); + final String display = StringUtils.getMergedLines(strings); + + final EntityType type = EntityType.NOTE; + final String code = line0.get(1); + getSystem().createEntity(code, display, type).setSpecificBackcolor(line0.get(2)); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java b/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java new file mode 100644 index 000000000..eecb929e2 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4765 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandMultilinesTitle extends CommandMultilines { + + public CommandMultilinesTitle(final UmlDiagram diagram) { + super(diagram, "(?i)^title$", "(?i)^end ?title$"); + } + + public CommandExecutionResult execute(List lines) { + final List strings = lines.subList(1, lines.size() - 1); + if (strings.size() > 0) { + getSystem().setTitle(strings); + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("No title defined"); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandNoteEntity.java b/src/net/sourceforge/plantuml/command/CommandNoteEntity.java new file mode 100644 index 000000000..2aba47b06 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandNoteEntity.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +final public class CommandNoteEntity extends SingleLineCommand { + + public CommandNoteEntity(AbstractEntityDiagram classDiagram) { + super( + classDiagram, + "(?i)^note\\s+(right|left|top|bottom)\\s+of\\s+([\\p{L}0-9_.]+|\\((?!\\*\\))[^\\)]+\\)|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\"|:[^:]+:)" + + "\\s*(#\\w+)?\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String pos = arg.get(0); + final IEntity cl1 = getSystem().getOrCreateClass(arg.get(1)); + final Entity note = getSystem().createEntity("GN" + UniqueSequence.getValue(), arg.get(3), EntityType.NOTE); + note.setSpecificBackcolor(arg.get(2)); + + final Link link; + final Position position = Position.valueOf(pos.toUpperCase()).withRankdir(getSystem().getRankdir()); + + final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getDashed(); + if (position == Position.RIGHT) { + link = new Link(cl1, note, type, null, 1); + } else if (position == Position.LEFT) { + link = new Link(note, cl1, type, null, 1); + } else if (position == Position.BOTTOM) { + link = new Link(cl1, note, type, null, 2); + } else if (position == Position.TOP) { + link = new Link(note, cl1, type, null, 2); + } else { + throw new IllegalArgumentException(); + } + getSystem().addLink(link); + return CommandExecutionResult.ok(); + + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandPackage.java b/src/net/sourceforge/plantuml/command/CommandPackage.java new file mode 100644 index 000000000..5d9bae12c --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandPackage.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5536 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class CommandPackage extends SingleLineCommand { + + public CommandPackage(AbstractEntityDiagram diagram) { + super(diagram, + "(?i)^package\\s+(\"[^\"]+\"|\\S+)(?:\\s+as\\s+([\\p{L}0-9_.]+))?\\s*(#[0-9a-fA-F]{6}|#?\\w+)?\\s*\\{?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code; + final String display; + if (arg.get(1) == null) { + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + display = code; + } else { + display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + code = arg.get(1); + } + final Group currentPackage = getSystem().getCurrentGroup(); +// if (getSystem().entityExist(code)) { +// return CommandExecutionResult.error("Package cannot have the same name as an existing class"); +// } + final Group p = getSystem().getOrCreateGroup(code, display, null, GroupType.PACKAGE, currentPackage); + p.setBold(true); + final String color = arg.get(2); + if (color != null) { + p.setBackColor(new HtmlColor(color)); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandPage.java b/src/net/sourceforge/plantuml/command/CommandPage.java new file mode 100644 index 000000000..fda580973 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandPage.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; + +public class CommandPage extends SingleLineCommand { + + public CommandPage(AbstractEntityDiagram classDiagram) { + super(classDiagram, "(?i)^page\\s+(\\d+)\\s*x\\s*(\\d+)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + + final int horizontal = Integer.parseInt(arg.get(0)); + final int vertical = Integer.parseInt(arg.get(1)); + if (horizontal <= 0 || vertical <= 0) { + return CommandExecutionResult.error("Argument must be positive"); + } + getSystem().setHorizontalPages(horizontal); + getSystem().setVerticalPages(vertical); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandPragma.java b/src/net/sourceforge/plantuml/command/CommandPragma.java new file mode 100644 index 000000000..b18aa6606 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandPragma.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandPragma extends SingleLineCommand { + + public CommandPragma(UmlDiagram system) { + super(system, "(?i)^!pragma\\s+([A-Za-z_][A-Za-z_0-9]*)(?:\\s+(.*))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + getSystem().getPragma().define(arg.get(0).toLowerCase(), arg.get(1)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandRotate.java b/src/net/sourceforge/plantuml/command/CommandRotate.java new file mode 100644 index 000000000..661ea5c61 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandRotate.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandRotate extends SingleLineCommand { + + public CommandRotate(UmlDiagram diagram) { + super(diagram, "(?i)^rotate$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + + getSystem().setRotation(true); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandScale.java b/src/net/sourceforge/plantuml/command/CommandScale.java new file mode 100644 index 000000000..b48762fd6 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandScale.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.ScaleSimple; +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandScale extends SingleLineCommand { + + public CommandScale(UmlDiagram diagram) { + super(diagram, "(?i)^scale\\s+([0-9.]+)(?:\\s*/\\s*([0-9.]+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + double scale = Double.parseDouble(arg.get(0)); + if (arg.get(1) != null) { + scale /= Double.parseDouble(arg.get(1)); + } + getSystem().setScale(new ScaleSimple(scale)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandScaleWidthAndHeight.java b/src/net/sourceforge/plantuml/command/CommandScaleWidthAndHeight.java new file mode 100644 index 000000000..ab5a030ad --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandScaleWidthAndHeight.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.ScaleWidthAndHeight; +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandScaleWidthAndHeight extends SingleLineCommand { + + public CommandScaleWidthAndHeight(UmlDiagram diagram) { + super(diagram, "(?i)^scale\\s+([0-9.]+)\\s*[*x]\\s*([0-9.]+)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final double width = Double.parseDouble(arg.get(0)); + final double height = Double.parseDouble(arg.get(1)); + getSystem().setScale(new ScaleWidthAndHeight(width, height)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandScaleWidthOrHeight.java b/src/net/sourceforge/plantuml/command/CommandScaleWidthOrHeight.java new file mode 100644 index 000000000..bda456820 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandScaleWidthOrHeight.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.ScaleHeight; +import net.sourceforge.plantuml.ScaleWidth; +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandScaleWidthOrHeight extends SingleLineCommand { + + public CommandScaleWidthOrHeight(UmlDiagram diagram) { + super(diagram, "(?i)^scale\\s+([0-9.]+)\\s+(width|height)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final double size = Double.parseDouble(arg.get(0)); + final boolean width = "width".equalsIgnoreCase(arg.get(1)); + if (width) { + getSystem().setScale(new ScaleWidth(size)); + } else { + getSystem().setScale(new ScaleHeight(size)); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandSkinParam.java b/src/net/sourceforge/plantuml/command/CommandSkinParam.java new file mode 100644 index 000000000..14625829c --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandSkinParam.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandSkinParam extends SingleLineCommand { + + public CommandSkinParam(UmlDiagram diagram) { + super(diagram, "(?i)^skinparam\\s+(\\w+)\\s+(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + getSystem().setParam(arg.get(0), arg.get(1)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandTitle.java b/src/net/sourceforge/plantuml/command/CommandTitle.java new file mode 100644 index 000000000..2da7a24fb --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandTitle.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandTitle extends SingleLineCommand { + + public CommandTitle(UmlDiagram diagram) { + super(diagram, "(?i)^title(?:\\s*:\\s*|\\s+)(.*[\\p{L}0-9_.].*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + getSystem().setTitle(StringUtils.getWithNewlines(arg.get(0))); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/PSystemCommandFactory.java b/src/net/sourceforge/plantuml/command/PSystemCommandFactory.java new file mode 100644 index 000000000..7d1f56fc3 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/PSystemCommandFactory.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; + +import net.sourceforge.plantuml.PSystemFactory; + +public interface PSystemCommandFactory extends PSystemFactory { + + CommandControl isValid(List lines); + + Command createCommand(List lines); +} diff --git a/src/net/sourceforge/plantuml/command/Position.java b/src/net/sourceforge/plantuml/command/Position.java new file mode 100644 index 000000000..e6848fa56 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/Position.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.command; + +import net.sourceforge.plantuml.cucadiagram.Rankdir; + +public enum Position { + RIGHT, LEFT, BOTTOM, TOP; + + public Position withRankdir(Rankdir rankdir) { + if (rankdir == null) { + throw new IllegalArgumentException(); + } + if (rankdir == Rankdir.TOP_TO_BOTTOM) { + // Default + return this; + } + if (this == RIGHT) { + return BOTTOM; + } + if (this == LEFT) { + return TOP; + } + if (this == BOTTOM) { + return RIGHT; + } + if (this == TOP) { + return LEFT; + } + throw new IllegalStateException(); + } +} diff --git a/src/net/sourceforge/plantuml/command/ProtectedCommand.java b/src/net/sourceforge/plantuml/command/ProtectedCommand.java new file mode 100644 index 000000000..6669f90bb --- /dev/null +++ b/src/net/sourceforge/plantuml/command/ProtectedCommand.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3828 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.util.List; + +import net.sourceforge.plantuml.Log; + +public class ProtectedCommand implements Command { + + private final Command cmd; + + public ProtectedCommand(Command cmd) { + this.cmd = cmd; + } + + public CommandExecutionResult execute(List lines) { + try { + return cmd.execute(lines); + } catch (Throwable t) { + t.printStackTrace(); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final PrintWriter pw = new PrintWriter(baos); + t.printStackTrace(pw); + Log.error("Error " + t); + String msg = "You should send a mail to plantuml@gmail.com with this log"; + Log.error(msg); + msg += " " + new String(baos.toByteArray()); + return CommandExecutionResult.error(msg); + } + } + + public String getHelpMessageForDeprecated(List lines) { + return cmd.getHelpMessageForDeprecated(lines); + } + + public boolean isDeprecated(List lines) { + return cmd.isDeprecated(lines); + } + + public CommandControl isValid(List lines) { + return cmd.isValid(lines); + } + +} diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand.java b/src/net/sourceforge/plantuml/command/SingleLineCommand.java new file mode 100644 index 000000000..b2a8d3e37 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand.java @@ -0,0 +1,138 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5041 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.PSystem; +import net.sourceforge.plantuml.StringUtils; + +public abstract class SingleLineCommand implements Command { + + private static final Set printed = new HashSet(); + + private final S system; + private final Pattern pattern; + + public SingleLineCommand(S system, String pattern) { + if (system == null) { + throw new IllegalArgumentException(); + } + if (pattern == null) { + throw new IllegalArgumentException(); + } + if (pattern.startsWith("(?i)^") == false || pattern.endsWith("$") == false) { + throw new IllegalArgumentException("Bad pattern " + pattern); + } + + if (printed.add(pattern) == true) { + // System.out.println(pattern); + } + + this.system = system; + this.pattern = Pattern.compile(pattern); + } + + final protected S getSystem() { + return system; + } + + final public CommandControl isValid(List lines) { + if (lines.size() != 1) { + return CommandControl.NOT_OK; + } + if (isCommandForbidden()) { + return CommandControl.NOT_OK; + } + final String line = lines.get(0).trim(); + final Matcher m = pattern.matcher(line); + final boolean result = m.find(); + if (result) { + actionIfCommandValid(); + } + return result ? CommandControl.OK : CommandControl.NOT_OK; + } + + protected boolean isCommandForbidden() { + return false; + } + + protected void actionIfCommandValid() { + } + + public final CommandExecutionResult execute(List lines) { + if (lines.size() != 1) { + throw new IllegalArgumentException(); + } + final String line = lines.get(0).trim(); + if (isForbidden(line)) { + return CommandExecutionResult.error("Forbidden line "+line); + } + final List arg = getSplit(line); + if (arg == null) { + return CommandExecutionResult.error("Cannot parse line "+line); + } + return executeArg(arg); + } + + protected boolean isForbidden(String line) { + return false; + } + + protected abstract CommandExecutionResult executeArg(List arg); + + final public List getSplit(String line) { + return StringUtils.getSplit(pattern, line); + } + + final public boolean isDeprecated(List lines) { + if (lines.size() != 1) { + return false; + } + return isDeprecated(lines.get(0)); + } + + public String getHelpMessageForDeprecated(List lines) { + return null; + } + + protected boolean isDeprecated(String line) { + return false; + } + +} diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java new file mode 100644 index 000000000..b9c019da3 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java @@ -0,0 +1,126 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5041 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.PSystem; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; + +public abstract class SingleLineCommand2 implements Command { + + private final S system; + private final RegexConcat pattern; + + public SingleLineCommand2(S system, RegexConcat pattern) { + if (system == null) { + throw new IllegalArgumentException(); + } + if (pattern == null) { + throw new IllegalArgumentException(); + } + if (pattern.getPattern().startsWith("^") == false || pattern.getPattern().endsWith("$") == false) { + throw new IllegalArgumentException("Bad pattern " + pattern.getPattern()); + } + + this.system = system; + this.pattern = pattern; + } + + final protected S getSystem() { + return system; + } + + final public CommandControl isValid(List lines) { + if (lines.size() != 1) { + return CommandControl.NOT_OK; + } + if (isCommandForbidden()) { + return CommandControl.NOT_OK; + } + final String line = lines.get(0).trim(); + final boolean result = pattern.match(line); + if (result) { + actionIfCommandValid(); + } + return result ? CommandControl.OK : CommandControl.NOT_OK; + } + + protected boolean isCommandForbidden() { + return false; + } + + protected void actionIfCommandValid() { + } + + public final CommandExecutionResult execute(List lines) { + if (lines.size() != 1) { + throw new IllegalArgumentException(); + } + final String line = lines.get(0).trim(); + if (isForbidden(line)) { + return CommandExecutionResult.error("Forbidden line " + line); + } + + final Map arg = pattern.matcher(line); + if (arg == null) { + return CommandExecutionResult.error("Cannot parse line " + line); + } + return executeArg(arg); + } + + protected boolean isForbidden(String line) { + return false; + } + + protected abstract CommandExecutionResult executeArg(Map arg); + + final public boolean isDeprecated(List lines) { + if (lines.size() != 1) { + return false; + } + return isDeprecated(lines.get(0)); + } + + public String getHelpMessageForDeprecated(List lines) { + return null; + } + + protected boolean isDeprecated(String line) { + return false; + } + +} diff --git a/src/net/sourceforge/plantuml/command/regex/IRegex.java b/src/net/sourceforge/plantuml/command/regex/IRegex.java new file mode 100644 index 000000000..05f06eb5e --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/IRegex.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.Iterator; +import java.util.Map; + +public interface IRegex { + + public String getPattern(); + + public int count(); + + public Map createPartialMatch(Iterator it); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/command/regex/MatcherIterator.java b/src/net/sourceforge/plantuml/command/regex/MatcherIterator.java new file mode 100644 index 000000000..aa4df25b0 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/MatcherIterator.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.Iterator; +import java.util.regex.Matcher; + +public class MatcherIterator implements Iterator { + + private int cpt = 1; + private final Matcher matcher; + + MatcherIterator(Matcher matcher) { + this.matcher = matcher; + } + + public boolean hasNext() { + return cpt <= matcher.groupCount(); + } + + public String next() { + return matcher.group(cpt++); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/regex/RegexComposed.java b/src/net/sourceforge/plantuml/command/regex/RegexComposed.java new file mode 100644 index 000000000..dbfea2245 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/RegexComposed.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class RegexComposed implements IRegex { + + private final List partials; + + abstract protected Pattern getFull(); + + public RegexComposed(IRegex... partial) { + this.partials = Arrays.asList(partial); + if (partials.size() < 2) { + throw new IllegalArgumentException(); + } + } + + public Map createPartialMatch(Iterator it) { + final Map result = new HashMap(); + for (IRegex r : partials) { + result.putAll(r.createPartialMatch(it)); + } + return result; + } + + final public int count() { + int cpt = getStartCount(); + for (IRegex r : partials) { + cpt += r.count(); + } + return cpt; + } + + protected int getStartCount() { + return 0; + } + + public Map matcher(String s) { + final Matcher matcher = getFull().matcher(s); + if (matcher.find() == false) { + throw new IllegalArgumentException(s); + } + + final Iterator it = new MatcherIterator(matcher); + return Collections.unmodifiableMap(createPartialMatch(it)); + } + + final public boolean match(String s) { + return getFull().matcher(s).find(); + } + + final public String getPattern() { + return getFull().pattern(); + } + + final protected List getPartials() { + return partials; + } + +} diff --git a/src/net/sourceforge/plantuml/command/regex/RegexConcat.java b/src/net/sourceforge/plantuml/command/regex/RegexConcat.java new file mode 100644 index 000000000..18410a9c7 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/RegexConcat.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.regex.Pattern; + +public class RegexConcat extends RegexComposed implements IRegex { + + private final Pattern full; + + public RegexConcat(IRegex... partial) { + super(partial); + final StringBuilder sb = new StringBuilder(); + for (IRegex p : partial) { + sb.append(p.getPattern()); + } + this.full = Pattern.compile(sb.toString()); + } + + @Override + protected Pattern getFull() { + return full; + } + + +} diff --git a/src/net/sourceforge/plantuml/command/regex/RegexLeaf.java b/src/net/sourceforge/plantuml/command/regex/RegexLeaf.java new file mode 100644 index 000000000..a9105448b --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/RegexLeaf.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.regex.Pattern; + +public class RegexLeaf implements IRegex { + + private final Pattern pattern; + private final String name; + + private int count = -1; + + public RegexLeaf(String regex) { + this(null, regex); + } + + public RegexLeaf(String name, String regex) { + this.pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); + this.name = name; + } + + public String getName() { + return name; + } + + public String getPattern() { + return pattern.pattern(); + } + + public int count() { + if (count == -1) { + count = pattern.matcher("").groupCount(); + } + return count; + } + + public Map createPartialMatch(Iterator it) { + final RegexPartialMatch m = new RegexPartialMatch(name); + for (int i = 0; i < count(); i++) { + final String group = it.next(); + m.add(group); + } + if (name == null) { + return Collections.emptyMap(); + } + return Collections.singletonMap(name, m); + } + +} diff --git a/src/net/sourceforge/plantuml/command/regex/RegexOr.java b/src/net/sourceforge/plantuml/command/regex/RegexOr.java new file mode 100644 index 000000000..b662868e4 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/RegexOr.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.regex.Pattern; + +public class RegexOr extends RegexComposed implements IRegex { + + private final Pattern full; + private final String name; + + public RegexOr(IRegex... partial) { + this(null, partial); + } + + public RegexOr(String name, IRegex... partial) { + super(partial); + this.name = name; + final StringBuilder sb = new StringBuilder("("); + if (name == null) { + sb.append("?:"); + } + for (IRegex p : partial) { + sb.append(p.getPattern()); + sb.append("|"); + } + sb.setLength(sb.length() - 1); + sb.append(')'); + this.full = Pattern.compile(sb.toString()); + } + + @Override + protected Pattern getFull() { + return full; + } + + protected int getStartCount() { + return 1; + } + + final public Map createPartialMatch(Iterator it) { + final Map result = new HashMap(); + final String fullGroup = name == null ? null : it.next(); + result.putAll(super.createPartialMatch(it)); + if (name != null) { + final RegexPartialMatch m = new RegexPartialMatch(name); + m.add(fullGroup); + result.put(name, m); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/command/regex/RegexPartialMatch.java b/src/net/sourceforge/plantuml/command/regex/RegexPartialMatch.java new file mode 100644 index 000000000..8f9e730f6 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/regex/RegexPartialMatch.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.command.regex; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +public class RegexPartialMatch implements Iterable { + + private final List data = new ArrayList(); + + public RegexPartialMatch(String name) { + + } + + public void add(String group) { + data.add(group); + } + + public int size() { + return data.size(); + } + + public String get(int i) { + return data.get(i); + } + + public Iterator iterator() { + return Collections.unmodifiableCollection(data).iterator(); + } + + @Override + public String toString() { + return "{" + data + "}"; + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/ComponentDiagram.java b/src/net/sourceforge/plantuml/componentdiagram/ComponentDiagram.java new file mode 100644 index 000000000..c68162281 --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/ComponentDiagram.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.componentdiagram; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class ComponentDiagram extends AbstractEntityDiagram { + + @Override + public IEntity getOrCreateClass(String code) { + if (code.startsWith("[") && code.endsWith("]")) { + return getOrCreateEntity(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code), + EntityType.COMPONENT); + } + if (code.startsWith(":") && code.endsWith(":")) { + return getOrCreateEntity(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code), EntityType.ACTOR); + } + if (code.startsWith("()")) { + code = code.substring(2).trim(); + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code); + return getOrCreateEntity(code, EntityType.CIRCLE_INTERFACE); + } + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code); + return getOrCreateEntity(code, EntityType.CIRCLE_INTERFACE); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.COMPONENT; + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/ComponentDiagramFactory.java b/src/net/sourceforge/plantuml/componentdiagram/ComponentDiagramFactory.java new file mode 100644 index 000000000..071dc9c60 --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/ComponentDiagramFactory.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5463 $ + * + */ +package net.sourceforge.plantuml.componentdiagram; + +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.command.CommandCreateNote; +import net.sourceforge.plantuml.command.CommandEndPackage; +import net.sourceforge.plantuml.command.CommandMultilinesStandaloneNote; +import net.sourceforge.plantuml.command.CommandNoteEntity; +import net.sourceforge.plantuml.command.CommandPackage; +import net.sourceforge.plantuml.command.CommandPage; +import net.sourceforge.plantuml.componentdiagram.command.CommandCreateActorInComponent; +import net.sourceforge.plantuml.componentdiagram.command.CommandCreateCircleInterface; +import net.sourceforge.plantuml.componentdiagram.command.CommandCreateComponent; +import net.sourceforge.plantuml.componentdiagram.command.CommandLinkComponent2; +import net.sourceforge.plantuml.componentdiagram.command.CommandMultilinesComponentNoteEntity; +import net.sourceforge.plantuml.usecasediagram.command.CommandRankDirUsecase; + +public class ComponentDiagramFactory extends AbstractUmlSystemCommandFactory { + + private ComponentDiagram system; + + public ComponentDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new ComponentDiagram(); + + addCommand(new CommandRankDirUsecase(system)); + addCommonCommands(system); + + addCommand(new CommandPage(system)); + //addCommand(new CommandLinkComponent(system)); + addCommand(new CommandLinkComponent2(system)); + + addCommand(new CommandPackage(system)); + addCommand(new CommandEndPackage(system)); + addCommand(new CommandNoteEntity(system)); + + addCommand(new CommandCreateNote(system)); + addCommand(new CommandCreateComponent(system)); + addCommand(new CommandCreateCircleInterface(system)); + addCommand(new CommandCreateActorInComponent(system)); + + addCommand(new CommandMultilinesComponentNoteEntity(system)); + addCommand(new CommandMultilinesStandaloneNote(system)); + + } +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java new file mode 100644 index 000000000..09bce8eca --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.componentdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandCreateActorInComponent extends SingleLineCommand { + + public CommandCreateActorInComponent(ComponentDiagram diagram) { + super( + diagram, + "(?i)^(?:actor\\s+)?([\\p{L}0-9_.]+|:[^:]+:|\"[^\"]+\")\\s*(?:as\\s+:?([\\p{L}0-9_.]+):?)?(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final EntityType type = EntityType.ACTOR; + final String code; + final String display; + if (arg.get(1) == null) { + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + display = code; + } else { + display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + } + final String stereotype = arg.get(2); + final Entity entity = (Entity) getSystem().getOrCreateEntity(code, type); + entity.setDisplay(display); + + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateCircleInterface.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateCircleInterface.java new file mode 100644 index 000000000..6d338752a --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateCircleInterface.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.componentdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandCreateCircleInterface extends SingleLineCommand { + + public CommandCreateCircleInterface(ComponentDiagram diagram) { + super( + diagram, + "(?i)^(?:interface\\s+)?(?:\\(\\)\\s*)?([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(?:as\\s+(?:\\(\\)\\s*)?([\\p{L}0-9_.]+))?(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final EntityType type = EntityType.CIRCLE_INTERFACE; + final String code; + final String display; + if (arg.get(1) == null) { + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + display = code; + } else { + display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + } + final String stereotype = arg.get(2); + // final Entity entity = getSystem().createEntity(code, display, type); + final Entity entity = (Entity) getSystem().getOrCreateEntity(code, type); + entity.setDisplay(display); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateComponent.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateComponent.java new file mode 100644 index 000000000..7c6cc8e1d --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateComponent.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.componentdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandCreateComponent extends SingleLineCommand { + + public CommandCreateComponent(ComponentDiagram diagram) { + super( + diagram, + "(?i)^(?:component\\s+)?([\\p{L}0-9_.]+|\\[[^\\]*]+[^\\]]*\\]|\"[^\"]+\")\\s*(?:as\\s+\\[?([\\p{L}0-9_.]+)\\]?)?(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final EntityType type = EntityType.COMPONENT; + final String code; + final String display; + if (arg.get(1) == null) { + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + display = code; + } else { + display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + } + final String stereotype = arg.get(2); + // final Entity entity = getSystem().createEntity(code, display, type); + final Entity entity = (Entity) getSystem().getOrCreateEntity(code, type); + entity.setDisplay(display); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent.java new file mode 100644 index 000000000..1f5747658 --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5443 $ + * + */ +package net.sourceforge.plantuml.componentdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandLinkComponent extends SingleLineCommand { + + public CommandLinkComponent(ComponentDiagram diagram) { + super( + diagram, + "(?i)^([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")\\s*" + + "(?:(" + + "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*|\\.+(?:left|right|up|down|le?|ri?|up?|do?)?\\.*)([\\]>]|\\|[>\\]])?" + + ")|(" + + "([\\[<]|[<\\[]\\|)?([=-]*(?:left|right|up|down|le?|ri?|up?|do?)?[=-]+|\\.*(?:left|right|up|down|le?|ri?|up?|do?)?\\.+)" + + "))" + + "\\s*([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")\\s*(?::\\s*([^\"]+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().isGroup(arg.get(0)) && getSystem().isGroup(arg.get(7))) { + return executePackageLink(arg); + } + if (getSystem().isGroup(arg.get(0)) || getSystem().isGroup(arg.get(7))) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final IEntity cl1 = getSystem().getOrCreateClass(arg.get(0)); + final IEntity cl2 = getSystem().getOrCreateClass(arg.get(7)); + + final LinkType linkType = arg.get(1) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); + final String queue = arg.get(1) != null ? arg.get(2) : arg.get(6); + + final Link link = new Link(cl1, cl2, linkType, arg.get(8), queue.length()); + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executePackageLink(List arg) { + final Group cl1 = getSystem().getGroup(arg.get(0)); + final Group cl2 = getSystem().getGroup(arg.get(7)); + + final LinkType linkType = arg.get(1) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); + final String queue = arg.get(1) != null ? arg.get(2) : arg.get(6); + + final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get(8), queue.length()); + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private LinkType getLinkTypeNormal(List arg) { + final String queue = arg.get(2); + final String key = arg.get(3); + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType; + } + + private LinkType getLinkTypeInv(List arg) { + final String queue = arg.get(6); + final String key = arg.get(5); + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType.getInv(); + } + + private LinkType getLinkTypeFromKey(String k) { + if (k == null) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + if (k.equals("<") || k.equals(">")) { + return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); + } + if (k.equals("<|") || k.equals("|>")) { + return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java new file mode 100644 index 000000000..94b76ce25 --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java @@ -0,0 +1,173 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5443 $ + * + */ +package net.sourceforge.plantuml.componentdiagram.command; + +import java.util.Map; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandLinkComponent2 extends SingleLineCommand2 { + + public CommandLinkComponent2(ComponentDiagram diagram) { + super(diagram, getRegex()); + } + + static RegexConcat getRegex() { + return new RegexConcat(new RegexLeaf("^"), getRegexGroup("G1"), new RegexLeaf("\\s*"), new RegexOr( + new RegexLeaf("AR_TO_RIGHT", + "(([-=.]+)(left|right|up|down|le?|ri?|up?|do?)?([-=.]*?\\.*)([\\]>]|\\|[>\\]])?)"), + new RegexLeaf("AR_TO_LEFT", + "(([\\[<]|[<\\[]\\|)?([-=.]*)(left|right|up|down|le?|ri?|up?|do?)?([-=.]+))")), + new RegexLeaf("\\s*"), getRegexGroup("G2"), new RegexLeaf("\\s*"), new RegexLeaf("END", + "(?::\\s*([^\"]+))?$")); + } + + private static RegexLeaf getRegexGroup(String name) { + return new RegexLeaf(name, + "([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")"); + } + + @Override + protected CommandExecutionResult executeArg(Map arg) { + final String g1 = arg.get("G1").get(0); + final String g2 = arg.get("G2").get(0); + + if (getSystem().isGroup(g1) && getSystem().isGroup(g2)) { + return executePackageLink(arg); + } + if (getSystem().isGroup(g1) || getSystem().isGroup(g2)) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final IEntity cl1 = getSystem().getOrCreateClass(g1); + final IEntity cl2 = getSystem().getOrCreateClass(g2); + + final LinkType linkType; + String queue; + if (arg.get("AR_TO_RIGHT").get(0) != null) { + queue = arg.get("AR_TO_RIGHT").get(1) + arg.get("AR_TO_RIGHT").get(3); + linkType = getLinkTypeNormal(queue, arg.get("AR_TO_RIGHT").get(4)); + } else { + queue = arg.get("AR_TO_LEFT").get(2) + arg.get("AR_TO_LEFT").get(4); + linkType = getLinkTypeNormal(queue, arg.get("AR_TO_LEFT").get(1)).getInv(); + } + final Direction dir = getDirection(arg); + + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + queue = "-"; + } + + Link link = new Link(cl1, cl2, linkType, arg.get("END").get(0), queue.length()); + + if (dir == Direction.LEFT || dir == Direction.UP) { + link = link.getInv(); + } + + + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private Direction getDirection(Map arg) { + if (arg.get("AR_TO_RIGHT").get(2) != null) { + return StringUtils.getQueueDirection(arg.get("AR_TO_RIGHT").get(2)); + } + if (arg.get("AR_TO_LEFT").get(3) != null) { + return StringUtils.getQueueDirection(arg.get("AR_TO_LEFT").get(3)).getInv(); + } + return null; + } + + + + private CommandExecutionResult executePackageLink(Map arg) { + final String g1 = arg.get("G1").get(0); + final String g2 = arg.get("G2").get(0); + + final Group cl1 = getSystem().getGroup(g1); + final Group cl2 = getSystem().getGroup(g2); + + final LinkType linkType; + final String queue; + if (arg.get("AR_TO_RIGHT").get(0) != null) { + queue = arg.get("AR_TO_RIGHT").get(1) + arg.get("AR_TO_RIGHT").get(3); + linkType = getLinkTypeNormal(queue, arg.get("AR_TO_RIGHT").get(4)); + } else { + queue = arg.get("AR_TO_LEFT").get(2) + arg.get("AR_TO_LEFT").get(4); + linkType = getLinkTypeNormal(queue, arg.get("AR_TO_LEFT").get(1)).getInv(); + + } + + final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get("END").get(0), + queue.length()); + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private LinkType getLinkTypeNormal(String queue, String key) { + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType; + } + + private LinkType getLinkTypeFromKey(String k) { + if (k == null) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + if (k.equals("<") || k.equals(">")) { + return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); + } + if (k.equals("<|") || k.equals("|>")) { + return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandMultilinesComponentNoteEntity.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandMultilinesComponentNoteEntity.java new file mode 100644 index 000000000..8cdb4a79e --- /dev/null +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandMultilinesComponentNoteEntity.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4239 $ + * + */ +package net.sourceforge.plantuml.componentdiagram.command; + +import net.sourceforge.plantuml.command.AbstractCommandMultilinesNoteEntity; +import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; + +public class CommandMultilinesComponentNoteEntity extends AbstractCommandMultilinesNoteEntity { + + public CommandMultilinesComponentNoteEntity(final ComponentDiagram system) { + super( + system, + "(?i)^note\\s+(right|left|top|bottom)\\s+(?:of\\s+)?([\\p{L}0-9_.]+|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\"|\\[[^\\]*]+[^\\]]*\\])\\s*(#\\w+)?$"); + } + +} diff --git a/src/net/sourceforge/plantuml/compositediagram/CompositeDiagram.java b/src/net/sourceforge/plantuml/compositediagram/CompositeDiagram.java new file mode 100644 index 000000000..bd1c3a35f --- /dev/null +++ b/src/net/sourceforge/plantuml/compositediagram/CompositeDiagram.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3851 $ + * + */ +package net.sourceforge.plantuml.compositediagram; + +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class CompositeDiagram extends AbstractEntityDiagram { + + @Override + public IEntity getOrCreateClass(String code) { + if (isGroup(code)) { + return getGroup(code).getEntityCluster(); + } + return getOrCreateEntity(code, EntityType.BLOCK); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.COMPOSITE; + } + +} diff --git a/src/net/sourceforge/plantuml/compositediagram/CompositeDiagramFactory.java b/src/net/sourceforge/plantuml/compositediagram/CompositeDiagramFactory.java new file mode 100644 index 000000000..ff796b985 --- /dev/null +++ b/src/net/sourceforge/plantuml/compositediagram/CompositeDiagramFactory.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3885 $ + * + */ +package net.sourceforge.plantuml.compositediagram; + +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.compositediagram.command.CommandCreateBlock; +import net.sourceforge.plantuml.compositediagram.command.CommandCreatePackageBlock; +import net.sourceforge.plantuml.compositediagram.command.CommandEndPackageBlock; +import net.sourceforge.plantuml.compositediagram.command.CommandLinkBlock; + +public class CompositeDiagramFactory extends AbstractUmlSystemCommandFactory { + + private CompositeDiagram system; + + public CompositeDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new CompositeDiagram(); + + addCommand(new CommandCreateBlock(system)); + addCommand(new CommandLinkBlock(system)); + addCommand(new CommandCreatePackageBlock(system)); + addCommand(new CommandEndPackageBlock(system)); + addCommonCommands(system); + } +} diff --git a/src/net/sourceforge/plantuml/compositediagram/command/CommandCreateBlock.java b/src/net/sourceforge/plantuml/compositediagram/command/CommandCreateBlock.java new file mode 100644 index 000000000..804e03b80 --- /dev/null +++ b/src/net/sourceforge/plantuml/compositediagram/command/CommandCreateBlock.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.compositediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.compositediagram.CompositeDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; + +public class CommandCreateBlock extends SingleLineCommand { + + public CommandCreateBlock(CompositeDiagram diagram) { + super(diagram, "(?i)^(?:block\\s+)(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + String display = arg.get(0); + final String code = arg.get(1); + if (display == null) { + display = code; + } + final Entity ent = (Entity) getSystem().getOrCreateClass(code); + ent.setDisplay(display); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/compositediagram/command/CommandCreatePackageBlock.java b/src/net/sourceforge/plantuml/compositediagram/command/CommandCreatePackageBlock.java new file mode 100644 index 000000000..933140160 --- /dev/null +++ b/src/net/sourceforge/plantuml/compositediagram/command/CommandCreatePackageBlock.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.compositediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.compositediagram.CompositeDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; + +public class CommandCreatePackageBlock extends SingleLineCommand { + + public CommandCreatePackageBlock(CompositeDiagram diagram) { + super(diagram, "(?i)^block\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)(?:\\s*\\{|\\s+begin)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + String display = arg.get(0); + final String code = arg.get(1); + if (display == null) { + display = code; + } + getSystem().getOrCreateGroup(code, display, null, GroupType.PACKAGE, currentPackage); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/compositediagram/command/CommandEndPackageBlock.java b/src/net/sourceforge/plantuml/compositediagram/command/CommandEndPackageBlock.java new file mode 100644 index 000000000..bddbf7da0 --- /dev/null +++ b/src/net/sourceforge/plantuml/compositediagram/command/CommandEndPackageBlock.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.compositediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.compositediagram.CompositeDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; + +public class CommandEndPackageBlock extends SingleLineCommand { + + public CommandEndPackageBlock(CompositeDiagram diagram) { + super(diagram, "(?i)^(end ?block|\\})$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + if (currentPackage == null) { + return CommandExecutionResult.error("No inner block defined"); + } + getSystem().endGroup(); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/compositediagram/command/CommandLinkBlock.java b/src/net/sourceforge/plantuml/compositediagram/command/CommandLinkBlock.java new file mode 100644 index 000000000..8764a5cf9 --- /dev/null +++ b/src/net/sourceforge/plantuml/compositediagram/command/CommandLinkBlock.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.compositediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.compositediagram.CompositeDiagram; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; + +public class CommandLinkBlock extends SingleLineCommand { + + public CommandLinkBlock(CompositeDiagram diagram) { + super(diagram, "(?i)^([\\p{L}0-9_.]+)\\s*(\\[\\]|\\*\\))?([=-]+|\\.+)(\\[\\]|\\(\\*)?\\s*([\\p{L}0-9_.]+)\\s*(?::\\s*(\\S*+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final IEntity cl1 = getSystem().getOrCreateClass(arg.get(0)); + final IEntity cl2 = getSystem().getOrCreateClass(arg.get(4)); + + final String deco1 = arg.get(1); + final String deco2 = arg.get(3); + LinkType linkType = new LinkType(getLinkDecor(deco1), getLinkDecor(deco2)); + + if ("*)".equals(deco1)) { + linkType = linkType.getInterfaceProvider(); + } else if ("(*".equals(deco2)) { + linkType = linkType.getInterfaceUser(); + } + + final String queue = arg.get(2); + + final Link link = new Link(cl1, cl2, linkType, arg.get(5), queue.length()); + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private LinkDecor getLinkDecor(String s) { + if ("[]".equals(s)) { + return LinkDecor.SQUARRE; + } + return LinkDecor.NONE; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/CrossingType.java b/src/net/sourceforge/plantuml/cucadiagram/CrossingType.java new file mode 100644 index 000000000..10e6decc7 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/CrossingType.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4994 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum CrossingType { + INSIDE, OUTSIDE, CUT, TOUCH_OUTSIDE, TOUCH_INSIDE, SELF + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java new file mode 100644 index 000000000..288927da2 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -0,0 +1,488 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5540 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMaker; +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMakerBeta; +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramPngMaker3; +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker; + +public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, PortionShower { + + private int horizontalPages = 1; + private int verticalPages = 1; + + private final Map entities = new TreeMap(); + private final Map nbLinks = new HashMap(); + + private final List links = new ArrayList(); + + private final Map groups = new LinkedHashMap(); + + private Group currentGroup = null; + private Rankdir rankdir = Rankdir.TOP_TO_BOTTOM; + + private boolean visibilityModifierPresent; + + public boolean hasUrl() { + for (IEntity entity : entities.values()) { + if (entity.getUrl() != null) { + return true; + } + } + return false; + } + + public IEntity getOrCreateEntity(String code, EntityType defaultType) { + IEntity result = entities.get(code); + if (result == null) { + result = createEntityInternal(code, code, defaultType, getCurrentGroup()); + } + return result; + } + + public Entity createEntity(String code, String display, EntityType type) { + if (entities.containsKey(code)) { + throw new IllegalArgumentException("Already known: " + code); + } + return createEntityInternal(code, display, type, getCurrentGroup()); + } + + final protected Entity createEntityInternal(String code, String display, EntityType type, Group group) { + if (display == null) { + display = code; + } + final Entity entity = new Entity(code, display, type, group); + entities.put(code, entity); + nbLinks.put(entity, 0); + return entity; + } + + public boolean entityExist(String code) { + return entities.containsKey(code); + } + + public void overideGroup(Group g, Entity proxy) { + if (groups.containsValue(g) == false) { + throw new IllegalArgumentException(); + } + if (entities.containsKey(proxy.getCode())) { + throw new IllegalArgumentException(); + } + if (entities.containsValue(proxy)) { + throw new IllegalArgumentException(); + } + for (final ListIterator it = links.listIterator(); it.hasNext();) { + final Link link = it.next(); + final Link newLink = link.mute(g, proxy); + if (newLink == null) { + it.remove(); + } else if (newLink != link) { + it.set(newLink); + } + } + groups.remove(g.getCode()); + assert groups.containsValue(g) == false; + + for (final Iterator it = entities.values().iterator(); it.hasNext();) { + final IEntity ent = it.next(); + if (ent.getParent() == g) { + it.remove(); + } + } + entities.put(proxy.getCode(), proxy); + } + + final public Collection getChildrenGroups(Group parent) { + final Collection result = new ArrayList(); + for (Group g : groups.values()) { + if (g.getParent() == parent) { + result.add(g); + } + } + // assert parent == null || result.size() == + // parent.getChildren().size(); + return Collections.unmodifiableCollection(result); + } + + public final Group getOrCreateGroup(String code, String display, String namespace, GroupType type, Group parent) { + final Group g = getOrCreateGroupInternal(code, display, namespace, type, parent); + currentGroup = g; + return g; + } + + protected final Group getOrCreateGroupInternal(String code, String display, String namespace, GroupType type, + Group parent) { +// if (entityExist(code)) { +// throw new IllegalArgumentException("code=" + code); +// } + Group g = groups.get(code); + if (g == null) { + g = new Group(code, display, namespace, type, parent); + groups.put(code, g); + + Entity entityGroup = entities.get(code); + if (entityGroup == null) { + entityGroup = new Entity("$$" + code, code, EntityType.GROUP, g); + } else { + entityGroup.muteToCluster(g); + } + g.setEntityCluster(entityGroup); + nbLinks.put(entityGroup, 0); + } + return g; + } + + public final Group getCurrentGroup() { + return currentGroup; + } + + public final Group getGroup(String code) { + final Group p = groups.get(code); + if (p == null) { + return null; + } + return p; + } + + public void endGroup() { + if (currentGroup == null) { + Log.error("No parent group"); + return; + } + currentGroup = currentGroup.getParent(); + } + + public final boolean isGroup(String code) { + return groups.containsKey(code); + } + + public final Collection getGroups() { + return Collections.unmodifiableCollection(groups.values()); + } + + final public Map entities() { + return Collections.unmodifiableMap(entities); + } + + final public void addLink(Link link) { + links.add(link); + inc(link.getEntity1()); + inc(link.getEntity2()); + } + + final protected void removeLink(Link link) { + final boolean ok = links.remove(link); + if (ok == false) { + throw new IllegalStateException(); + } + } + + private void inc(IEntity ent) { + if (ent == null) { + throw new IllegalArgumentException(); + } + nbLinks.put(ent, nbLinks.get(ent) + 1); + } + + final public List getLinks() { + return Collections.unmodifiableList(links); + } + + final public int getHorizontalPages() { + return horizontalPages; + } + + final public void setHorizontalPages(int horizontalPages) { + this.horizontalPages = horizontalPages; + } + + final public int getVerticalPages() { + return verticalPages; + } + + final public void setVerticalPages(int verticalPages) { + this.verticalPages = verticalPages; + } + + final public List createPng2(File pngFile) throws IOException, InterruptedException { + final CucaDiagramPngMaker3 maker = new CucaDiagramPngMaker3(this); + return maker.createPng(pngFile); + } + + final public void createPng2(OutputStream os) throws IOException { + final CucaDiagramPngMaker3 maker = new CucaDiagramPngMaker3(this); + maker.createPng(os); + } + + abstract protected List getDotStrings(); + + final public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, + InterruptedException { + + if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { + return createFilesTxt(suggestedFile, fileFormat); + } + + if (OptionFlags.getInstance().useJavaInsteadOfDot()) { + return createPng2(suggestedFile); + } + if (getUmlDiagramType() == UmlDiagramType.COMPOSITE || (BETA && getUmlDiagramType() == UmlDiagramType.CLASS)) { + final CucaDiagramFileMakerBeta maker = new CucaDiagramFileMakerBeta(this); + return maker.createFile(suggestedFile, getDotStrings(), fileFormat); + } + final CucaDiagramFileMaker maker = new CucaDiagramFileMaker(this); + return maker.createFile(suggestedFile, getDotStrings(), fileFormat); + } + + private List createFilesTxt(File suggestedFile, FileFormat fileFormat) throws IOException { + final CucaDiagramTxtMaker maker = new CucaDiagramTxtMaker(this, fileFormat); + return maker.createFiles(suggestedFile); + } + + public static boolean BETA = false; + + final public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { + createFilesTxt(os, index, fileFormat); + return; + } + + if (getUmlDiagramType() == UmlDiagramType.COMPOSITE) { + final CucaDiagramFileMakerBeta maker = new CucaDiagramFileMakerBeta(this); + try { + maker.createFile(os, getDotStrings(), fileFormat); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new IOException(e.toString()); + } + return; + } + final CucaDiagramFileMaker maker = new CucaDiagramFileMaker(this); + try { + maker.createFile(os, getDotStrings(), fileFormat); + } catch (InterruptedException e) { + Log.error(e.toString()); + throw new IOException(e.toString()); + } + } + + private void createFilesTxt(OutputStream os, int index, FileFormat fileFormat) { + throw new UnsupportedOperationException(); + // TODO Auto-generated method stub + } + + public final Rankdir getRankdir() { + return rankdir; + } + + public final void setRankdir(Rankdir rankdir) { + this.rankdir = rankdir; + } + + public boolean isAutarkic(Group g) { + if (g.getType() == GroupType.PACKAGE) { + return false; + } + if (g.getType() == GroupType.INNER_ACTIVITY) { + return true; + } + if (g.getType() == GroupType.CONCURRENT_ACTIVITY) { + return true; + } + if (g.getType() == GroupType.CONCURRENT_STATE) { + return true; + } + if (getChildrenGroups(g).size() > 0) { + return false; + } + for (Link link : links) { + final IEntity e1 = link.getEntity1(); + final IEntity e2 = link.getEntity2(); + if (e1.getParent() != g && e2.getParent() == g && e2.getType() != EntityType.GROUP) { + return false; + } + if (e2.getParent() != g && e1.getParent() == g && e1.getType() != EntityType.GROUP) { + return false; + } + if (link.isAutolink(g)) { + continue; + } + if (e1.getType() == EntityType.GROUP && e2.getParent() == e1.getParent() && e1.getParent() == g) { + return false; + } + if (e2.getType() == EntityType.GROUP && e2.getParent() == e1.getParent() && e1.getParent() == g) { + return false; + } + + } + return true; + // return false; + } + + private static boolean isNumber(String s) { + return s.matches("[+-]?(\\.?\\d+|\\d+\\.\\d*)"); + } + + public void resetPragmaLabel() { + getPragma().undefine("labeldistance"); + getPragma().undefine("labelangle"); + } + + public String getLabeldistance() { + if (getPragma().isDefine("labeldistance")) { + final String s = getPragma().getValue("labeldistance"); + if (isNumber(s)) { + return s; + } + } + if (getPragma().isDefine("defaultlabeldistance")) { + final String s = getPragma().getValue("defaultlabeldistance"); + if (isNumber(s)) { + return s; + } + } + // Default in dot 1.0 + return "1.7"; + } + + public String getLabelangle() { + if (getPragma().isDefine("labelangle")) { + final String s = getPragma().getValue("labelangle"); + if (isNumber(s)) { + return s; + } + } + if (getPragma().isDefine("defaultlabelangle")) { + final String s = getPragma().getValue("defaultlabelangle"); + if (isNumber(s)) { + return s; + } + } + // Default in dot -25 + return "25"; + } + + final public boolean isEmpty(Group gToTest) { + for (Group g : groups.values()) { + if (g == gToTest) { + continue; + } + if (g.getParent() == gToTest) { + return false; + } + } + return gToTest.entities().size() == 0; + } + + public final boolean isVisibilityModifierPresent() { + return visibilityModifierPresent; + } + + public final void setVisibilityModifierPresent(boolean visibilityModifierPresent) { + this.visibilityModifierPresent = visibilityModifierPresent; + } + + private boolean isAutonom(Group g) { + for (Link link : links) { + final CrossingType type = g.getCrossingType(link); + if (type == CrossingType.CUT) { + return false; + } + } + return true; + } + + public final void computeAutonomyOfGroups() { + for (Group g : groups.values()) { + g.setAutonom(isAutonom(g)); + } + } + + public final boolean showPortion(EntityPortion portion, IEntity entity) { + boolean result = true; + for (HideOrShow cmd : hideOrShows) { + if (cmd.portion == portion && cmd.gender.contains(entity)) { + result = cmd.show; + } + } + return result; + } + + public final void hideOrShow(EntityGender gender, Set portions, boolean show) { + for (EntityPortion portion : portions) { + this.hideOrShows.add(new HideOrShow(gender, portion, show)); + } + } + + private final List hideOrShows = new ArrayList(); + + static class HideOrShow { + private final EntityGender gender; + private final EntityPortion portion; + private final boolean show; + + public HideOrShow(EntityGender gender, EntityPortion portion, boolean show) { + this.gender = gender; + this.portion = portion; + this.show = show; + } + } + + @Override + public int getNbImages() { + return this.horizontalPages * this.verticalPages; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Entity.java b/src/net/sourceforge/plantuml/cucadiagram/Entity.java new file mode 100644 index 000000000..843348233 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Entity.java @@ -0,0 +1,229 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5186 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class Entity implements IEntity { + + private final String code; + private String display; + + private final String uid; + private EntityType type; + + private Stereotype stereotype; + + private final List fields2 = new ArrayList(); + private final List methods2 = new ArrayList(); + + private Group container; + + private DrawFile imageFile; + private String url; + + public Entity(String code, String display, EntityType type, Group entityPackage) { + this("cl" + UniqueSequence.getValue(), code, display, type, entityPackage); + + } + + public Entity(String uid, String code, String display, EntityType type, Group entityPackage) { + if (code == null || code.length() == 0) { + throw new IllegalArgumentException(); + } + if (display == null /* || display.length() == 0 */) { + throw new IllegalArgumentException(); + } + this.uid = uid; + this.type = type; + this.code = code; + this.display = display; + this.container = entityPackage; + if (entityPackage != null && type != EntityType.GROUP) { + entityPackage.addEntity(this); + } + } + + public void setEntityPackage(Group entityPackage) { + if (entityPackage == null) { + throw new IllegalArgumentException(); + } + if (this.container != null) { + throw new IllegalStateException(); + } + this.container = entityPackage; + entityPackage.addEntity(this); + } + + public void addFieldOrMethod(String s) { + if (isMethod(s)) { + methods2.add(new Member(s)); + } else { + addField(s); + } + } + + public void addField(String s) { + fields2.add(new Member(s)); + } + + public void addField(Member s) { + fields2.add(s); + } + + private boolean isMethod(String s) { + return s.contains("(") || s.contains(")"); + } + + public List methods2() { + return Collections.unmodifiableList(methods2); + } + + public List fields2() { + return Collections.unmodifiableList(fields2); + } + + public EntityType getType() { + return type; + } + + public void muteToType(EntityType newType) { + if (type != EntityType.ABSTRACT_CLASS && type != EntityType.CLASS && type != EntityType.ENUM + && type != EntityType.INTERFACE) { + throw new IllegalArgumentException("type=" + type); + } + if (newType != EntityType.ABSTRACT_CLASS && newType != EntityType.CLASS && newType != EntityType.ENUM + && newType != EntityType.INTERFACE) { + throw new IllegalArgumentException("newtype=" + newType); + } + this.type = newType; + } + + public String getCode() { + return code; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + + public String getUid() { + return uid; + } + + public Stereotype getStereotype() { + return stereotype; + } + + public final void setStereotype(Stereotype stereotype) { + this.stereotype = stereotype; + } + + public final Group getParent() { + return container; + } + + @Override + public String toString() { + if (type == EntityType.GROUP) { + return display + "(" + getType() + ")" + this.container; + } + return display + "(" + getType() + ")"; + } + + public void muteToCluster(Group newGroup) { + if (type == EntityType.GROUP) { + throw new IllegalStateException(); + } + this.type = EntityType.GROUP; + this.container = newGroup; + } + + public void moveTo(Group dest) { + this.container = dest; + dest.addEntity(this); + } + + public final DrawFile getImageFile() { + return imageFile; + } + + public final void setImageFile(DrawFile imageFile) { + this.imageFile = imageFile; + } + + private HtmlColor specificBackcolor; + + public HtmlColor getSpecificBackColor() { + return specificBackcolor; + } + + public void setSpecificBackcolor(String s) { + this.specificBackcolor = HtmlColor.getColorIfValid(s); + } + + public final String getUrl() { + return url; + // return "http://www.google.com"; + } + + public final void setUrl(String url) { + this.url = url; + } + + @Override + public int hashCode() { + return uid.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + final IEntity other = (IEntity) obj; + return uid.equals(other.getUid()); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityGender.java b/src/net/sourceforge/plantuml/cucadiagram/EntityGender.java new file mode 100644 index 000000000..de49ecad2 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityGender.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public interface EntityGender { + public boolean contains(IEntity test); +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java b/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java new file mode 100644 index 000000000..e98630d63 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityGenderUtils.java @@ -0,0 +1,123 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public class EntityGenderUtils { + + static public EntityGender byEntityType(final EntityType type) { + return new EntityGender() { + public boolean contains(IEntity test) { + return test.getType() == type; + } + }; + } + + static public EntityGender byEntityAlone(final IEntity entity) { + return new EntityGender() { + public boolean contains(IEntity test) { + return test == entity; + } + }; + } + + static public EntityGender byStereotype(final String stereotype) { + return new EntityGender() { + public boolean contains(IEntity test) { + if (test.getStereotype() == null) { + return false; + } + return stereotype.equals(test.getStereotype().getLabel()); + } + }; + } + + static public EntityGender byPackage(final Group group) { + if (group == null) { + throw new IllegalArgumentException(); + } + return new EntityGender() { + public boolean contains(IEntity test) { + if (test.getParent() == null) { + return false; + } + if (group == test.getParent()) { + return true; + } + return false; + } + }; + } + + static public EntityGender and(final EntityGender g1, final EntityGender g2) { + return new EntityGender() { + public boolean contains(IEntity test) { + return g1.contains(test) && g2.contains(test); + } + }; + } + + + static public EntityGender all() { + return new EntityGender() { + public boolean contains(IEntity test) { + return true; + } + }; + } + + static public EntityGender emptyMethods() { + return new EntityGender() { + public boolean contains(IEntity test) { + return test.methods2().size()==0; + } + }; + } + + static public EntityGender emptyFields() { + return new EntityGender() { + public boolean contains(IEntity test) { + return test.fields2().size()==0; + } + }; + } + + static public EntityGender emptyMembers() { + return new EntityGender() { + public boolean contains(IEntity test) { + return test.methods2().size()==0 && test.fields2().size()==0; + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityPortion.java b/src/net/sourceforge/plantuml/cucadiagram/EntityPortion.java new file mode 100644 index 000000000..2dac4464c --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityPortion.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum EntityPortion { + FIELD, METHOD, CIRCLED_CHARACTER, STEREOTYPE, LOLLIPOP, ENTIRELY +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityType.java b/src/net/sourceforge/plantuml/cucadiagram/EntityType.java new file mode 100644 index 000000000..e0c41098e --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityType.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5190 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum EntityType { + + EMPTY_PACKAGE, + + ABSTRACT_CLASS, CLASS, INTERFACE, LOLLIPOP, ENUM, ACTOR, USECASE, COMPONENT, CIRCLE_INTERFACE, NOTE, OBJECT, + + ACTIVITY, BRANCH, SYNCHRO_BAR, CIRCLE_START, CIRCLE_END, POINT_FOR_ASSOCIATION, ACTIVITY_CONCURRENT, + + STATE, STATE_CONCURRENT, + + BLOCK, + + GROUP; + + public static EntityType getEntityType(String arg0) { + arg0 = arg0.toUpperCase(); + if (arg0.startsWith("ABSTRACT")) { + return EntityType.ABSTRACT_CLASS; + } + return EntityType.valueOf(arg0); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java b/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java new file mode 100644 index 000000000..d282e87d0 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java @@ -0,0 +1,114 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4749 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.util.List; + +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public abstract class EntityUtils { + + private static IEntity withNoParent(final IEntity ent) { + if (ent.getType() == EntityType.GROUP) { + throw new IllegalArgumentException(); + } + return new IEntity() { + public List fields2() { + return ent.fields2(); + } + + public String getDisplay() { + return ent.getDisplay(); + } + + public Group getParent() { + return null; + } + + public Stereotype getStereotype() { + return ent.getStereotype(); + } + + public EntityType getType() { + return ent.getType(); + } + + public String getUid() { + return ent.getUid(); + } + + public String getUrl() { + return ent.getUrl(); + } + + public List methods2() { + return ent.methods2(); + } + + public DrawFile getImageFile() { + return ent.getImageFile(); + } + + public HtmlColor getSpecificBackColor() { + return ent.getSpecificBackColor(); + } + + public void setSpecificBackcolor(String specificBackcolor) { + throw new UnsupportedOperationException(); + } + + @Override + public int hashCode() { + return ent.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return ent.equals(obj); + } + + @Override + public String toString() { + return "NoParent " + ent.toString(); + } + + public String getCode() { + return ent.getCode(); + } + + }; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Group.java b/src/net/sourceforge/plantuml/cucadiagram/Group.java new file mode 100644 index 000000000..083008b27 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Group.java @@ -0,0 +1,263 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5190 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class Group { + + private final Map entities = new LinkedHashMap(); + private final String code; + private final String display; + private final String namespace; + + private HtmlColor backColor; + private final Group parent; + private final Collection children = new ArrayList(); + + private boolean dashed; + private boolean rounded; + private boolean bold; + + private final GroupType type; + + private IEntity entityCluster; + private boolean autonom = true; + private Rankdir rankdir = Rankdir.TOP_TO_BOTTOM; + + private final int cpt = UniqueSequence.getValue(); + + public Group(String code, String display, String namespace, GroupType type, Group parent) { + if (type == null) { + throw new IllegalArgumentException(); + } + if (code == null || code.length() == 0) { + throw new IllegalArgumentException(); + } + if (parent != null) { + if (parent.children.contains(this)) { + throw new IllegalArgumentException(); + } + parent.children.add(this); + } + this.namespace = namespace; + this.type = type; + this.parent = parent; + this.code = code; + this.display = display; + } + + @Override + public String toString() { + return "G[code=" + code + "]" + entities + " autonom=" + isAutonom(); + } + + public void addEntity(Entity entity) { + if (entities.containsValue(entity)) { + throw new IllegalArgumentException(); + } + if (entities.containsKey(entity.getCode())) { + throw new IllegalArgumentException(entity.getCode()); + } + if (entity.getType() == EntityType.GROUP) { + throw new IllegalArgumentException(); + } + entities.put(entity.getCode(), entity); + } + + // private boolean containsFully(Link link) { + // return contains((Entity) link.getEntity1()) && contains((Entity) + // link.getEntity2()); + // } + + public boolean contains(IEntity entity) { + if (entity == null) { + throw new IllegalArgumentException(); + } + if (entity.equals(entityCluster)) { + throw new IllegalArgumentException(); + } + if (entities.containsValue(entity)) { + return true; + } + for (Group child : getChildren()) { + if (child.contains(entity)) { + return true; + } + } + return false; + } + + public CrossingType getCrossingType(Link link) { + if (link.getEntity1().equals(this.entityCluster) && link.getEntity2().equals(this.entityCluster)) { + return CrossingType.SELF; + } + if (link.getEntity1().equals(this.entityCluster)) { + if (contains(link.getEntity2())) { + return CrossingType.TOUCH_INSIDE; + } + return CrossingType.TOUCH_OUTSIDE; + } + if (link.getEntity2().equals(this.entityCluster)) { + if (contains(link.getEntity1())) { + return CrossingType.TOUCH_INSIDE; + } + return CrossingType.TOUCH_OUTSIDE; + } + final boolean contains1 = contains(link.getEntity1()); + final boolean contains2 = contains(link.getEntity2()); + if (contains1 && contains2) { + return CrossingType.INSIDE; + } + if (contains1 == false && contains2 == false) { + return CrossingType.OUTSIDE; + } + return CrossingType.CUT; + + } + + public Map entities() { + return Collections.unmodifiableMap(entities); + } + + public String getCode() { + return code; + } + + public String getUid() { + return "cluster" + cpt; + } + + public final HtmlColor getBackColor() { + return backColor; + } + + public final void setBackColor(HtmlColor backColor) { + this.backColor = backColor; + } + + public final Group getParent() { + return parent; + } + + public final boolean isDashed() { + return dashed; + } + + public final void setDashed(boolean dashed) { + this.dashed = dashed; + } + + public final boolean isRounded() { + return rounded; + } + + public final void setRounded(boolean rounded) { + this.rounded = rounded; + } + + public GroupType getType() { + return type; + } + + public final IEntity getEntityCluster() { + if (entityCluster == null) { + throw new IllegalStateException(); + } + return entityCluster; + } + + public final void setEntityCluster(IEntity entityCluster) { + if (entityCluster == null) { + throw new IllegalArgumentException(); + } + this.entityCluster = entityCluster; + } + + // public boolean isEmpty() { + // return entities.isEmpty(); + // } + + public String getDisplay() { + return display; + } + + public boolean isBold() { + return bold; + } + + public void setBold(boolean bold) { + this.bold = bold; + } + + public void moveEntitiesTo(Group dest) { + for (IEntity ent : entities.values()) { + ((Entity) ent).moveTo(dest); + } + entities.clear(); + + } + + public String getNamespace() { + return namespace; + } + + public final Collection getChildren() { + return Collections.unmodifiableCollection(children); + } + + public final boolean isAutonom() { + return autonom; + } + + public final void setAutonom(boolean autonom) { + this.autonom = autonom; + } + + public final Rankdir getRankdir() { + return rankdir; + } + + public final void setRankdir(Rankdir rankdir) { + this.rankdir = rankdir; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java b/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java new file mode 100644 index 000000000..ade2a5ed7 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupHierarchy.java @@ -0,0 +1,43 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4192 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.util.Collection; + +public interface GroupHierarchy { + + public Collection getChildrenGroups(Group parent); + + public boolean isEmpty(Group g); +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupType.java b/src/net/sourceforge/plantuml/cucadiagram/GroupType.java new file mode 100644 index 000000000..9ba5fe1a6 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupType.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5190 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum GroupType { + + PACKAGE, STATE, CONCURRENT_STATE, INNER_ACTIVITY, CONCURRENT_ACTIVITY +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java new file mode 100644 index 000000000..643a3207d --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4749 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.util.List; + +import net.sourceforge.plantuml.SpecificBackcolorable; + +public interface IEntity extends Imaged, SpecificBackcolorable { + + public Group getParent(); + + public String getDisplay(); + + public EntityType getType(); + + public String getUid(); + + public String getUrl(); + + public List fields2(); + + public Stereotype getStereotype(); + + public List methods2(); + + public String getCode(); + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Imaged.java b/src/net/sourceforge/plantuml/cucadiagram/Imaged.java new file mode 100644 index 000000000..f4f76e3d5 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Imaged.java @@ -0,0 +1,41 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4003 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; + +public interface Imaged { + + public DrawFile getImageFile(); +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java new file mode 100644 index 000000000..4c1e26374 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -0,0 +1,248 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5425 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; + +public class Link implements Imaged { + + final private IEntity cl1; + final private IEntity cl2; + final private LinkType type; + final private String label; + + final private int length; + final private String qualifier1; + final private String qualifier2; + final private String uid = "LNK" + UniqueSequence.getValue(); + + private DrawFile imageFile; + private String note; + private boolean invis = false; + private int weight = 1; + + private final String labeldistance; + private final String labelangle; + + public Link(IEntity cl1, IEntity cl2, LinkType type, String label, int length) { + this(cl1, cl2, type, label, length, null, null, null, null); + } + + public Link(IEntity cl1, IEntity cl2, LinkType type, String label, int length, String qualifier1, + String qualifier2, String labeldistance, String labelangle) { + if (length < 1) { + throw new IllegalArgumentException(); + } + if (cl1 == null || cl2 == null) { + throw new IllegalArgumentException(); + } + this.cl1 = cl1; + this.cl2 = cl2; + this.type = type; + this.label = label; + this.length = length; + this.qualifier1 = qualifier1; + this.qualifier2 = qualifier2; + this.labeldistance = labeldistance; + this.labelangle = labelangle; + } + + public Link getInv() { + return new Link(cl2, cl1, type.getInv(), label, length, qualifier2, qualifier1, labeldistance, labelangle); + } + + public String getLabeldistance() { + // Default in dot 1.0 + return labeldistance; + } + + public String getLabelangle() { + // Default in dot -25 + return labelangle; + } + + public String getUid() { + return uid; + } + + public final boolean isInvis() { + return invis; + } + + public final void setInvis(boolean invis) { + this.invis = invis; + } + + private static IEntity muteProxy(IEntity ent, Group g, IEntity proxy) { + if (ent.getParent() == g) { + return proxy; + } + return ent; + } + + public Link mute(Group g, Entity proxy) { + if (cl1.getParent() == g && cl1.getType() != EntityType.GROUP && cl2.getParent() == g + && cl2.getType() != EntityType.GROUP) { + return null; + } + final IEntity ent1 = muteProxy(cl1, g, proxy); + final IEntity ent2 = muteProxy(cl2, g, proxy); + if (this.cl1 == ent1 && this.cl2 == ent2) { + return this; + } + return new Link(ent1, ent2, type, label, length, qualifier1, qualifier2, labeldistance, labelangle); + } + + public boolean isBetween(IEntity cl1, IEntity cl2) { + if (cl1.equals(this.cl1) && cl2.equals(this.cl2)) { + return true; + } + if (cl1.equals(this.cl2) && cl2.equals(this.cl1)) { + return true; + } + return false; + } + + @Override + public String toString() { + return super.toString() + " " + cl1 + "-->" + cl2; + } + + public IEntity getEntity1() { + return cl1; + } + + public IEntity getEntity2() { + return cl2; + } + + public LinkType getType() { + return type; + } + + public String getLabel() { + return label; + } + + public int getLength() { + return length; + } + + public String getQualifier1() { + return qualifier1; + } + + public String getQualifier2() { + return qualifier2; + } + + public final int getWeight() { + return weight; + } + + public final void setWeight(int weight) { + this.weight = weight; + } + + public final String getNote() { + return note; + } + + public final void setNote(String note) { + this.note = note; + } + + public DrawFile getImageFile() { + return imageFile; + } + + public void setImageFile(DrawFile imageFile) { + this.imageFile = imageFile; + } + + public boolean isAutolink(Group g) { + if (getEntity1() == g.getEntityCluster() && getEntity2() == g.getEntityCluster()) { + return true; + } + return false; + } + + public boolean isToEdgeLink(Group g) { + if (getEntity1().getParent() != g || getEntity2().getParent() != g) { + return false; + } + assert getEntity1().getParent() == g && getEntity2().getParent() == g; + if (isAutolink(g)) { + return false; + } + + if (getEntity2().getType() == EntityType.GROUP) { + assert getEntity1().getType() != EntityType.GROUP; + return true; + } + return false; + } + + public boolean isFromEdgeLink(Group g) { + if (getEntity1().getParent() != g || getEntity2().getParent() != g) { + return false; + } + assert getEntity1().getParent() == g && getEntity2().getParent() == g; + if (isAutolink(g)) { + return false; + } + + if (getEntity1().getType() == EntityType.GROUP) { + assert getEntity2().getType() != EntityType.GROUP; + return true; + } + return false; + } + + public boolean containsType(EntityType type) { + if (getEntity1().getType() == type || getEntity2().getType() == type) { + return true; + } + return false; + } + + public boolean contains(IEntity entity) { + if (getEntity1() == entity || getEntity2() == entity) { + return true; + } + return false; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java b/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java new file mode 100644 index 000000000..db6297592 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4604 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum LinkDecor { + + NONE(2), EXTENDS(30), COMPOSITION(15), AGREGATION(15), ARROW(10), PLUS(0), SQUARRE(30); + + private final int size; + + private LinkDecor(int size) { + this.size = size; + } + + public String getArrowDot() { + if (this == LinkDecor.NONE) { + return "none"; + } else if (this == LinkDecor.EXTENDS) { + return "empty"; + } else if (this == LinkDecor.COMPOSITION) { + return "diamond"; + } else if (this == LinkDecor.AGREGATION) { + return "ediamond"; + } else if (this == LinkDecor.ARROW) { + return "open"; + } else if (this == LinkDecor.PLUS) { + return "odot"; + } else { + throw new UnsupportedOperationException(); + } + } + + public int getSize() { + return size; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkStyle.java b/src/net/sourceforge/plantuml/cucadiagram/LinkStyle.java new file mode 100644 index 000000000..4f197a645 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkStyle.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4604 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum LinkStyle { + + NORMAL, DASHED, INTERFACE_PROVIDER, INTERFACE_USER; + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkType.java b/src/net/sourceforge/plantuml/cucadiagram/LinkType.java new file mode 100644 index 000000000..38e27c3da --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkType.java @@ -0,0 +1,150 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4604 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public class LinkType { + + private final LinkDecor decor1; + private final LinkStyle style; + private final LinkDecor decor2; + + public LinkType(LinkDecor decor1, LinkDecor decor2) { + this(decor1, LinkStyle.NORMAL, decor2); + } + + public boolean contains(LinkDecor decors) { + return decor1 == decors || decor2 == decors; + } + + @Override + public String toString() { + return decor1 + "-" + style + "-" + decor2; + } + + @Override + public int hashCode() { + return toString().hashCode(); + } + + @Override + public boolean equals(Object obj) { + final LinkType other = (LinkType) obj; + return this.decor1 == other.decor1 && this.decor2 == other.decor2 && this.style == other.style; + } + + private LinkType(LinkDecor decor1, LinkStyle style, LinkDecor decor2) { + this.decor1 = decor1; + this.style = style; + this.decor2 = decor2; + } + + public boolean isDashed() { + return style == LinkStyle.DASHED; + } + + public LinkType getDashed() { + return new LinkType(decor1, LinkStyle.DASHED, decor2); + } + + public LinkType getInterfaceProvider() { + return new LinkType(decor1, LinkStyle.INTERFACE_PROVIDER, decor2); + } + + public LinkType getInterfaceUser() { + return new LinkType(decor1, LinkStyle.INTERFACE_USER, decor2); + } + + public LinkType getInv() { + return new LinkType(decor2, style, decor1); + } + + public String getSpecificDecoration() { + final StringBuilder sb = new StringBuilder(); + + if (decor1 == LinkDecor.NONE && decor2 != LinkDecor.NONE) { + sb.append("dir=back,"); + } + if (decor1 != LinkDecor.NONE && decor2 != LinkDecor.NONE) { + sb.append("dir=both,"); + } + + sb.append("arrowtail="); + sb.append(decor2.getArrowDot()); + sb.append(",arrowhead="); + sb.append(decor1.getArrowDot()); + + if (decor1 == LinkDecor.EXTENDS || decor2 == LinkDecor.EXTENDS) { + sb.append(",arrowsize=2"); + } + if (decor1 == LinkDecor.PLUS || decor2 == LinkDecor.PLUS) { + sb.append(",arrowsize=1.5"); + } + + if (style == LinkStyle.DASHED) { + sb.append(",style=dashed"); + } + + return sb.toString(); + } + + public final LinkDecor getDecor1() { + return decor1; + } + + public final LinkStyle getStyle() { + return style; + } + + public final LinkDecor getDecor2() { + return decor2; + } + + public boolean isExtendsOrAgregationOrCompositionOrPlus() { + return isExtends() || isAgregationOrComposition() || isPlus(); + } + + private boolean isExtends() { + return decor1 == LinkDecor.EXTENDS || decor2 == LinkDecor.EXTENDS; + } + + private boolean isPlus() { + return decor1 == LinkDecor.PLUS || decor2 == LinkDecor.PLUS; + } + + private boolean isAgregationOrComposition() { + return decor1 == LinkDecor.AGREGATION || decor2 == LinkDecor.AGREGATION || decor1 == LinkDecor.COMPOSITION + || decor2 == LinkDecor.COMPOSITION; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Member.java b/src/net/sourceforge/plantuml/cucadiagram/Member.java new file mode 100644 index 000000000..1f77b8556 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Member.java @@ -0,0 +1,150 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4749 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import net.sourceforge.plantuml.skin.VisibilityModifier; + +public class Member { + + private String display; + private final boolean staticModifier; + private final boolean abstractModifier; + + private boolean privateModifier; + private boolean protectedModifier; + private boolean publicModifier; + private boolean packagePrivateModifier; + + public Member(String display) { + final String lower = display.toLowerCase(); + this.staticModifier = lower.contains("{static}") || lower.contains("{classifier}"); + this.abstractModifier = lower.contains("{abstract}"); + final String displayClean = display.replaceAll("(?i)\\{(static|classifier|abstract)\\}", "").trim(); + + if (VisibilityModifier.isVisibilityCharacter(displayClean.charAt(0))) { + updateVisibility(display.charAt(0)); + this.display = displayClean.substring(1).trim(); + } else { + this.display = displayClean; + } + assert VisibilityModifier.isVisibilityCharacter(this.display.charAt(0)) == false; + + } + + private void updateVisibility(char c) { + if (c == '-') { + this.privateModifier = true; + } + if (c == '#') { + this.protectedModifier = true; + } + if (c == '+') { + this.publicModifier = true; + } + if (c == '~') { + this.packagePrivateModifier = true; + } + + } + + public String getDisplay(boolean withVisibilityChar) { + if (withVisibilityChar) { + return getDisplayWithVisibilityChar(); + } + return getDisplayWithoutVisibilityChar(); + } + + + public String getDisplayWithoutVisibilityChar() { + assert VisibilityModifier.isVisibilityCharacter(display.charAt(0)) == false; + return display; + } + + + public String getDisplayWithVisibilityChar() { + if (isPrivate()) { + return "-" + display; + } + if (isPublic()) { + return "+" + display; + } + if (isPackagePrivate()) { + return "~" + display; + } + if (isProtected()) { + return "#" + display; + } + return display; + } + + @Override + public boolean equals(Object obj) { + final Member other = (Member) obj; + return this.display.equals(other.display); + } + + @Override + public int hashCode() { + return display.hashCode(); + } + + public final boolean isStatic() { + return staticModifier; + } + + public final boolean isAbstract() { + return abstractModifier; + } + + public final boolean isVisibilityModified() { + return privateModifier || publicModifier || protectedModifier || packagePrivateModifier; + } + + public final boolean isPrivate() { + return privateModifier; + } + + public final boolean isProtected() { + return protectedModifier; + } + + public final boolean isPublic() { + return publicModifier; + } + + public final boolean isPackagePrivate() { + return packagePrivateModifier; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/PortionShower.java b/src/net/sourceforge/plantuml/cucadiagram/PortionShower.java new file mode 100644 index 000000000..d6adc8762 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/PortionShower.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4192 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + + +public interface PortionShower { + + boolean showPortion(EntityPortion portion, IEntity entity); +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Rankdir.java b/src/net/sourceforge/plantuml/cucadiagram/Rankdir.java new file mode 100644 index 000000000..eeba9c4f6 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Rankdir.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum Rankdir { + LEFT_TO_RIGHT, TOP_TO_BOTTOM + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/RuleType.java b/src/net/sourceforge/plantuml/cucadiagram/RuleType.java new file mode 100644 index 000000000..fa6710c95 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/RuleType.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +public enum RuleType { + SHOW, HIDE +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java new file mode 100644 index 000000000..130f0f3f9 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -0,0 +1,130 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4111 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.awt.Color; +import java.awt.Font; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class Stereotype implements CharSequence { + + private final static Pattern circle = Pattern + .compile("\\<\\<\\s*\\(?(\\S)\\s*,\\s*(#[0-9a-fA-F]{6}|\\w+)\\s*(?:[),](.*?))?\\>\\>"); + + private final String label; + private final HtmlColor htmlColor; + private final char character; + private final double radius; + private final Font circledFont; + + public Stereotype(String label, double radius, Font circledFont) { + if (label == null) { + throw new IllegalArgumentException(); + } + if (label.startsWith("<<") == false || label.endsWith(">>") == false) { + throw new IllegalArgumentException(label); + } + this.radius = radius; + this.circledFont = circledFont; + final Matcher m = circle.matcher(label); + if (m.find()) { + if (StringUtils.isNotEmpty(m.group(3))) { + this.label = "<<" + m.group(3) + ">>"; + } else { + this.label = null; + } + this.htmlColor = new HtmlColor(m.group(2)); + this.character = m.group(1).charAt(0); + } else { + this.label = label; + this.character = '\0'; + this.htmlColor = null; + } + } + + public Color getColor() { + if (htmlColor == null) { + return null; + } + return htmlColor.getColor(); + } + + public char getCharacter() { + return character; + } + + public String getLabel() { + return label; + } + + public boolean isSpotted() { + return character != 0; + } + + @Override + public String toString() { + if (label == null) { + return "" + character; + } + if (character == 0) { + return label; + } + return character + " " + label; + } + + public char charAt(int arg0) { + return toString().charAt(arg0); + } + + public int length() { + return toString().length(); + } + + public CharSequence subSequence(int arg0, int arg1) { + return toString().subSequence(arg0, arg1); + } + + public double getRadius() { + return radius; + } + + public final Font getCircledFont() { + return circledFont; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java new file mode 100644 index 000000000..78c3c295f --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java @@ -0,0 +1,169 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.GraphicStrings; + +abstract class AbstractGraphviz implements Graphviz { + + private final File dotExe; + private final String dotString; + private final String[] type; + + static boolean isWindows() { + return File.separatorChar == '\\'; + } + + AbstractGraphviz(String dotString, String... type) { + if (type == null) { + throw new IllegalArgumentException(); + } + this.dotExe = searchDotExe(); + this.dotString = dotString; + this.type = type; + } + + private File searchDotExe() { + if (OptionFlags.getInstance().getDotExecutable() == null) { + final String getenv = GraphvizUtils.getenvGraphvizDot(); + if (getenv == null) { + return specificDotExe(); + } + return new File(getenv); + } + + return new File(OptionFlags.getInstance().getDotExecutable()); + + } + + abstract protected File specificDotExe(); + + final public void createPng(OutputStream os) throws IOException, InterruptedException { + if (dotString == null) { + throw new IllegalArgumentException(); + } + + if (illegalDotExe()) { + createPngNoGraphviz(os, FileFormat.valueOf(type[0].toUpperCase())); + return; + } + final String cmd = getCommandLine(); + try { + Log.info("Starting Graphviz process " + cmd); + Log.info("DotString size: " + dotString.length()); + final ProcessRunner p = new ProcessRunner(cmd); + p.run(dotString.getBytes(), os); + Log.info("Ending process ok"); + } catch (Throwable e) { + e.printStackTrace(); + Log.error("Error: " + e); + Log.error("The command was " + cmd); + Log.error(""); + Log.error("Try java -jar plantuml.jar -testdot to figure out the issue"); + Log.error(""); + } finally { + Log.info("Ending Graphviz process"); + + } + } + + private boolean illegalDotExe() { + return dotExe == null || dotExe.isFile() == false || dotExe.canRead() == false; + } + + final public String dotVersion() throws IOException, InterruptedException { + final String cmd = getCommandLineVersion(); + return executeCmd(cmd); + } + + private String executeCmd(final String cmd) throws IOException, InterruptedException { + final ProcessRunner p = new ProcessRunner(cmd); + p.run(null, null); + final StringBuilder sb = new StringBuilder(); + if (StringUtils.isNotEmpty(p.getOut())) { + sb.append(p.getOut()); + } + if (StringUtils.isNotEmpty(p.getError())) { + if (sb.length() > 0) { + sb.append(' '); + } + sb.append(p.getError()); + } + return sb.toString().replace('\n', ' ').trim(); + } + + final private void createPngNoGraphviz(OutputStream os, FileFormat format) throws IOException { + final List msg = new ArrayList(); + msg.add("Dot Executable: " + dotExe); + if (dotExe != null) { + if (dotExe.exists() == false) { + msg.add("File does not exist"); + } else if (dotExe.isDirectory()) { + msg.add("It should be an executable, not a directory"); + } else if (dotExe.isFile() == false) { + msg.add("Not a valid file"); + } else if (dotExe.canRead() == false) { + msg.add("File cannot be read"); + } + } + msg.add("Cannot find Graphviz: try 'java -jar plantuml.jar -testdot'"); + final GraphicStrings errorResult = new GraphicStrings(msg); + errorResult.writeImage(os, format); + } + + abstract String getCommandLine(); + + abstract String getCommandLineVersion(); + + public final File getDotExe() { + return dotExe; + } + + protected final void appendImageType(final StringBuilder sb) { + for (String t : type) { + sb.append(" -T" + t + " "); + } + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java new file mode 100644 index 000000000..17fa5026b --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java @@ -0,0 +1,813 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5503 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.Scale; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Imaged; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.eps.EpsStrategy; +import net.sourceforge.plantuml.eps.SvgToEpsConverter; +import net.sourceforge.plantuml.graphic.CircledCharacter; +import net.sourceforge.plantuml.graphic.GraphicStrings; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.VerticalPosition; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.png.PngRotation; +import net.sourceforge.plantuml.png.PngScaler; +import net.sourceforge.plantuml.png.PngSizer; +import net.sourceforge.plantuml.png.PngSplitter; +import net.sourceforge.plantuml.png.PngTitler; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.skin.VisibilityModifier; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.svg.SvgTitler; +import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; +import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; + +public final class CucaDiagramFileMaker { + + private final CucaDiagram diagram; + private final StaticFiles staticFiles; + private final Rose rose = new Rose(); + + static private final StringBounder stringBounder; + + static { + final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); + stringBounder = StringBounderUtils.asStringBounder(builder.getGraphics2D()); + } + + public CucaDiagramFileMaker(CucaDiagram diagram) throws IOException { + HtmlColor.setForceMonochrome(diagram.getSkinParam().isMonochrome()); + this.diagram = diagram; + this.staticFiles = new StaticFiles(diagram.getSkinParam()); + } + + static String changeName(String name) { + return name.replaceAll("(?i)\\.png$", ".cmapx"); + } + + public List createFile(File suggested, List dotStrings, FileFormat fileFormat) throws IOException, + InterruptedException { + + OutputStream os = null; + try { + os = new FileOutputStream(suggested); + final String cmap = createFile(os, dotStrings, fileFormat); + if (diagram.hasUrl() && fileFormat == FileFormat.PNG) { + final File cmapFile = new File(changeName(suggested.getAbsolutePath())); + final PrintWriter pw = new PrintWriter(cmapFile); + pw.print(cmap); + pw.close(); + } + } finally { + if (os != null) { + os.close(); + } + } + + if (fileFormat == FileFormat.PNG) { + final List result = new PngSplitter(suggested, diagram.getHorizontalPages(), + diagram.getVerticalPages(), diagram.getMetadata()).getFiles(); + for (File f : result) { + Log.info("Creating file: " + f); + } + return result; + } + Log.info("Creating file: " + suggested); + return Arrays.asList(suggested); + } + + static private void traceDotString(String dotString) throws IOException { + final File f = new File("dottmpfile" + UniqueSequence.getValue() + ".tmp"); + PrintWriter pw = null; + try { + pw = new PrintWriter(new FileWriter(f)); + pw.print(dotString); + Log.info("Creating file " + f); + } finally { + if (pw != null) { + pw.close(); + } + } + + } + + public String createFile(OutputStream os, List dotStrings, FileFormat fileFormat) throws IOException, + InterruptedException { + if (fileFormat == FileFormat.PNG) { + return createPng(os, dotStrings); + } else if (fileFormat == FileFormat.SVG) { + return createSvg(os, dotStrings); + } else if (fileFormat == FileFormat.EPS_VIA_SVG) { + return createEpsViaSvg(os, dotStrings); + } else if (fileFormat == FileFormat.EPS) { + return createEps(os, dotStrings); + } else { + throw new UnsupportedOperationException(); + } + + } + + private String createEpsViaSvg(OutputStream os, List dotStrings) throws IOException, InterruptedException { + final File svgTmp = createTempFile("svgtmp", ".svg"); + final FileOutputStream svgOs = new FileOutputStream(svgTmp); + final String status = createSvg(svgOs, dotStrings); + svgOs.close(); + final SvgToEpsConverter converter = new SvgToEpsConverter(svgTmp); + converter.createEps(os); + return status; + } + + private double deltaY; + + private String createSvg(OutputStream os, List dotStrings) throws IOException, InterruptedException { + + try { + deltaY = 0; + populateImages(); + populateImagesLink(); + final GraphvizMaker dotMaker = createDotMaker(staticFiles.getStaticImages(), + staticFiles.getVisibilityImages(), dotStrings, FileFormat.SVG); + final String dotString = dotMaker.createDotString(); + + if (OptionFlags.getInstance().isKeepTmpFiles()) { + traceDotString(dotString); + } + + // final boolean isUnderline = dotMaker.isUnderline(); + final Graphviz graphviz = GraphvizUtils.create(dotString, "svg"); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + dotMaker.clean(); + + String svg = new String(baos.toByteArray(), "UTF-8"); + + final Dimension2D dim = getDimensionSvg(svg); + if (dim != null) { + svg = removeSvgXmlHeader(svg); + + svg = addTitleSvg(svg, dim.getWidth(), dim.getHeight()); + svg = addHeaderSvg(svg, dim.getWidth(), dim.getHeight()); + svg = addFooterSvg(svg, dim.getWidth(), dim.getHeight()); + + // Image management + final Pattern pImage = Pattern.compile("(?i)]*>"); + final Matcher mImage = pImage.matcher(svg); + final StringBuffer sb = new StringBuffer(); + while (mImage.find()) { + final String image = mImage.group(0); + final String href = getValue(image, "href"); + final double widthSvg = Double.parseDouble(getValuePx(image, "width")); + final double heightSvg = Double.parseDouble(getValuePx(image, "height")); + final double x = Double.parseDouble(getValue(image, "x")); + final double y = Double.parseDouble(getValue(image, "y")); + final DrawFile drawFile = getDrawFileFromHref(href); + final int widthPng = drawFile.getWidthPng(); + final int heightPng = drawFile.getHeightPng(); + String svg2 = drawFile.getSvg(); + final String scale = getScale(widthSvg, heightSvg, widthPng, heightPng); + svg2 = svg2 + .replaceFirst("<[gG]>", ""); + mImage.appendReplacement(sb, svg2); + } + mImage.appendTail(sb); + svg = sb.toString(); + } + + os.write(svg.getBytes("UTF-8")); + + // final ByteArrayInputStream bais = new + // ByteArrayInputStream(baos.toByteArray()); + // BufferedImage im = ImageIO.read(bais); + // bais.close(); + // if (isUnderline) { + // new UnderlineTrick(im, new Color(Integer.parseInt("FEFECF", 16)), + // Color.BLACK).process(); + // } + // + // final Color background = + // diagram.getSkinParam().getBackgroundColor().getColor(); + // im = addTitle(im, background); + // im = addFooter(im, background); + // im = addHeader(im, background); + // + // if (diagram.isRotation()) { + // im = PngRotation.process(im); + // } + // im = PngSizer.process(im, diagram.getMinwidth()); + // + // PngIO.write(im, os, diagram.getMetadata()); + } finally { + // cleanTemporaryFiles(diagram.entities().values()); + // cleanTemporaryFiles(diagram.getLinks()); + } + return null; + } + + private static String removeSvgXmlHeader(String svg) { + svg = svg + .replaceFirst( + "(?i)]*>", + ""); + return svg; + } + + private Dimension2D getDimensionSvg(String svg) { + final Pattern p = Pattern.compile("(?i)]*points=\"([^\"]+)\""); + final Matcher m = p.matcher(svg); + if (m.find() == false) { + return null; + } + final String points = m.group(1); + final StringTokenizer st = new StringTokenizer(points, " "); + double minX = Double.MAX_VALUE; + double minY = Double.MAX_VALUE; + double maxX = -Double.MAX_VALUE; + double maxY = -Double.MAX_VALUE; + while (st.hasMoreTokens()) { + final String token = st.nextToken(); + final StringTokenizer st2 = new StringTokenizer(token, ","); + final double x = Double.parseDouble(st2.nextToken().trim()); + final double y = Double.parseDouble(st2.nextToken().trim()); + if (x < minX) { + minX = x; + } + if (y < minY) { + minY = y; + } + if (x > maxX) { + maxX = x; + } + if (y > maxY) { + maxY = y; + } + } + return new Dimension2DDouble(maxX - minX, maxY - minY); + } + + private DrawFile getDrawFileFromHref(final String href) throws IOException { + final DrawFile drawFile = staticFiles.getDrawFile(href); + if (drawFile != null) { + return drawFile; + } + final File searched = new File(href).getCanonicalFile(); + + for (Entity ent : diagram.entities().values()) { + final DrawFile df = ent.getImageFile(); + if (df == null) { + continue; + } + if (df.getPng().getCanonicalFile().equals(searched)) { + return df; + } + } + for (Link ent : diagram.getLinks()) { + final DrawFile df = ent.getImageFile(); + if (df == null) { + continue; + } + if (df.getPng().getCanonicalFile().equals(searched)) { + return df; + } + } + return drawFile; + } + + private String getScale(double widthSvg, double heightSvg, double widthPng, double heightPng) { + final double v1 = heightSvg / heightPng; + final double v2 = widthSvg / widthPng; + final double min = Math.min(v1, v2); + return "scale(" + min + " " + min + ")"; + } + + static String getValue(String s, String param) { + final Pattern p = Pattern.compile("(?i)" + param + "=\"([^\"]+)\""); + final Matcher m = p.matcher(s); + m.find(); + return m.group(1); + } + + static String getValuePx(String s, String param) { + final Pattern p = Pattern.compile("(?i)" + param + "=\"([^\"]+?)(?:px)?\""); + final Matcher m = p.matcher(s); + m.find(); + return m.group(1); + } + + private String createPng(OutputStream os, List dotStrings) throws IOException, InterruptedException { + + final StringBuilder cmap = new StringBuilder(); + try { + populateImages(); + populateImagesLink(); + final GraphvizMaker dotMaker = createDotMaker(staticFiles.getStaticImages(), + staticFiles.getVisibilityImages(), dotStrings, FileFormat.PNG); + final String dotString = dotMaker.createDotString(); + + if (OptionFlags.getInstance().isKeepTmpFiles()) { + traceDotString(dotString); + } + + final byte[] imageData = getImageData(dotString, cmap); + + if (isPngHeader(imageData, 0) == false) { + createError(os, imageData.length, FileFormat.PNG, "No PNG header found", + "Try -forcegd or -forcecairo flag"); + return null; + } + + if (imageData.length == 0) { + createError(os, imageData.length, FileFormat.PNG, "imageData.length == 0"); + return null; + } + + final ByteArrayInputStream bais = new ByteArrayInputStream(imageData); + BufferedImage im = ImageIO.read(bais); + if (im == null) { + createError(os, imageData.length, FileFormat.PNG, "im == null"); + return null; + } + bais.close(); + dotMaker.clean(); + + final boolean isUnderline = dotMaker.isUnderline(); + if (isUnderline) { + new UnderlineTrick(im, new Color(Integer.parseInt("FEFECF", 16)), Color.BLACK).process(); + } + + final Color background = diagram.getSkinParam().getBackgroundColor().getColor(); + im = addTitle(im, background); + im = addFooter(im, background); + im = addHeader(im, background); + im = scaleImage(im, diagram.getScale()); + + if (diagram.isRotation()) { + im = PngRotation.process(im); + } + im = PngSizer.process(im, diagram.getMinwidth()); + PngIO.write(im, os, diagram.getMetadata()); + } finally { + cleanTemporaryFiles(diagram.entities().values()); + cleanTemporaryFiles(diagram.getLinks()); + } + + if (cmap.length() > 0) { + return cmap.toString(); + } + return null; + } + + private BufferedImage scaleImage(BufferedImage im, Scale scale) { + if (scale==null) { + return im; + } + return PngScaler.scale(im, scale.getScale(im.getWidth(), im.getHeight())); + } + + private byte[] getImageDataCmap(final String dotString, StringBuilder cmap2) throws IOException, + InterruptedException { + final Graphviz graphviz = GraphvizUtils.create(dotString, "cmapx", getPngType()); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + + final byte[] allData = baos.toByteArray(); + Log.info("Reading " + allData.length + " bytes from dot"); + + final int pngStart = getPngStart(allData); + + final String cmap = new String(allData, 0, pngStart, "UTF8"); + Log.info("CMAP is " + cmap.length() + " long"); + cmap2.append(cmap); + + final byte[] imageData = new byte[allData.length - pngStart]; + System.arraycopy(allData, pngStart, imageData, 0, imageData.length); + + Log.info("PNG is " + imageData.length + " bytes from dot"); + return imageData; + } + + private int getPngStart(byte[] allData) throws IOException { + for (int i = 0; i < allData.length - 8; i++) { + if (isPngHeader(allData, i)) { + return i; + } + } + throw new IOException("Cannot find PNG header"); + } + + private boolean isPngHeader(byte[] allData, int i) { + if (i + 7 >= allData.length) { + return false; + } + return allData[i] == (byte) 0x89 && allData[i + 1] == (byte) 0x50 && allData[i + 2] == (byte) 0x4E + && allData[i + 3] == (byte) 0x47 && allData[i + 4] == (byte) 0x0D && allData[i + 5] == (byte) 0x0A + && allData[i + 6] == (byte) 0x1A && allData[i + 7] == (byte) 0x0A; + } + + private byte[] getImageData(final String dotString, StringBuilder cmap) throws IOException, InterruptedException { + if (diagram.hasUrl()) { + return getImageDataCmap(dotString, cmap); + } + final Graphviz graphviz = GraphvizUtils.create(dotString, getPngType()); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + + final byte[] imageData = baos.toByteArray(); + Log.info("Reading " + imageData.length + " bytes from dot"); + // File f = new File("dummy.png"); + // FileOutputStream fos = new FileOutputStream(f); + // fos.write(imageData); + // fos.close(); + return imageData; + } + + private String getPngType() { + if (OptionFlags.getInstance().isForceCairo()) { + return "png:cairo"; + } + if (OptionFlags.getInstance().isForceGd()) { + return "png:gd"; + } + return "png"; + } + + void createError(OutputStream os, int length, FileFormat fileFormat, String... supp) throws IOException { + final List msg = new ArrayList(); + msg.add("Error: Reading " + length + " byte(s) from dot"); + msg.add("Error reading the generated image"); + for (String s : supp) { + msg.add(s); + } + final GraphicStrings errorResult = new GraphicStrings(msg); + errorResult.writeImage(os, fileFormat); + } + + private BufferedImage addTitle(BufferedImage im, final Color background) { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.TITLE).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.TITLE); + final int fontSize = getSkinParam().getFontSize(FontParam.TITLE); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getTitle(), fontSize, fontFamily, + HorizontalAlignement.CENTER, VerticalPosition.TOP); + return pngTitler.processImage(im, background, 3); + } + + private String addTitleSvg(String svg, double width, double height) throws IOException { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.TITLE).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.TITLE); + final int fontSize = getSkinParam().getFontSize(FontParam.TITLE); + + final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getTitle(), fontSize, fontFamily, + HorizontalAlignement.CENTER, VerticalPosition.TOP, 3); + this.deltaY += svgTitler.getHeight(); + return svgTitler.addTitleSvg(svg, width, height); + } + + private String addHeaderSvg(String svg, double width, double height) throws IOException { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.HEADER); + final int fontSize = getSkinParam().getFontSize(FontParam.HEADER); + final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, + diagram.getHeaderAlignement(), VerticalPosition.TOP, 3); + this.deltaY += svgTitler.getHeight(); + return svgTitler.addTitleSvg(svg, width, height); + } + + private String addFooterSvg(String svg, double width, double height) throws IOException { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.FOOTER); + final int fontSize = getSkinParam().getFontSize(FontParam.FOOTER); + final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, + diagram.getFooterAlignement(), VerticalPosition.BOTTOM, 3); + return svgTitler.addTitleSvg(svg, width, height + deltaY); + } + + private BufferedImage addFooter(BufferedImage im, final Color background) { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.FOOTER); + final int fontSize = getSkinParam().getFontSize(FontParam.FOOTER); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, + diagram.getFooterAlignement(), VerticalPosition.BOTTOM); + return pngTitler.processImage(im, background, 3); + } + + private BufferedImage addHeader(BufferedImage im, final Color background) throws IOException { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.HEADER); + final int fontSize = getSkinParam().getFontSize(FontParam.HEADER); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, + diagram.getHeaderAlignement(), VerticalPosition.TOP); + return pngTitler.processImage(im, background, 3); + } + + private void cleanTemporaryFiles(final Collection imageFiles) throws IOException { + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + for (Imaged entity : imageFiles) { + if (entity.getImageFile() != null) { + entity.getImageFile().delete(); + } + } + } + } + + private GraphvizMaker createDotMaker(Map staticImages, + Map visibilities, List dotStrings, FileFormat fileFormat) + throws IOException, InterruptedException { + if (diagram.getUmlDiagramType() == UmlDiagramType.STATE + || diagram.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + new CucaDiagramSimplifier(diagram, dotStrings, fileFormat); + } + final DotData dotData = new DotData(null, diagram.getLinks(), diagram.entities(), diagram.getUmlDiagramType(), + diagram.getSkinParam(), diagram.getRankdir(), diagram, diagram); + + dotData.putAllStaticImages(staticImages); + if (diagram.isVisibilityModifierPresent()) { + dotData.putAllVisibilityImages(visibilities); + } + + return new DotMaker(dotData, dotStrings, fileFormat); + } + + private void populateImages() throws IOException { + for (Entity entity : diagram.entities().values()) { + final DrawFile f = createImage(entity); + if (f != null) { + entity.setImageFile(f); + } + } + } + + private void populateImagesLink() throws IOException { + for (Link link : diagram.getLinks()) { + final String note = link.getNote(); + if (note == null) { + continue; + } + final DrawFile f = createImageForNote(note, null); + if (f != null) { + link.setImageFile(f); + } + } + } + + DrawFile createImage(Entity entity) throws IOException { + if (entity.getType() == EntityType.NOTE) { + return createImageForNote(entity.getDisplay(), entity.getSpecificBackColor()); + } + if (entity.getType() == EntityType.ACTIVITY) { + return createImageForActivity(entity); + } + if (entity.getType() == EntityType.ABSTRACT_CLASS || entity.getType() == EntityType.CLASS + || entity.getType() == EntityType.ENUM || entity.getType() == EntityType.INTERFACE) { + return createImageForCircleCharacter(entity); + } + return null; + } + + private DrawFile createImageForNote(String display, HtmlColor backColor) throws IOException { + final File fPng = createTempFile("plantumlB", ".png"); + + final Rose skin = new Rose(); + + final ISkinParam skinParam = new SkinParamBackcolored(getSkinParam(), backColor); + final Component comp = skin + .createComponent(ComponentType.NOTE, skinParam, StringUtils.getWithNewlines(display)); + + final int width = (int) comp.getPreferredWidth(stringBounder); + final int height = (int) comp.getPreferredHeight(stringBounder); + + final Color background = diagram.getSkinParam().getBackgroundColor().getColor(); + final EmptyImageBuilder builder = new EmptyImageBuilder(width, height, background); + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + comp.drawU(new UGraphicG2d(g2d, null), new Dimension(width, height), new SimpleContext2D(false)); + PngIO.write(im, fPng); + g2d.dispose(); + + final UGraphicSvg ug = new UGraphicSvg(true); + comp.drawU(ug, new Dimension(width, height), new SimpleContext2D(false)); + + final File fEps = createTempFile("plantumlB", ".eps"); + final PrintWriter pw = new PrintWriter(fEps); + final UGraphicEps uEps = new UGraphicEps(EpsStrategy.getDefault()); + comp.drawU(uEps, new Dimension(width, height), new SimpleContext2D(false)); + pw.print(uEps.getEPSCode()); + pw.close(); + + return new DrawFile(fPng, getSvg(ug), fEps); + } + + static public String getSvg(UGraphicSvg ug) throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ug.createXml(baos); + baos.close(); + final String s = new String(baos.toByteArray(), "UTF-8"); + final Pattern p = Pattern.compile("(?i)"); + final Matcher m = p.matcher(s); + m.find(); + return m.group(0); + } + + private DrawFile createImageForActivity(Entity entity) throws IOException { + return null; + } + + private DrawFile createImageForCircleCharacter(Entity entity) throws IOException { + final Stereotype stereotype = entity.getStereotype(); + + if (stereotype == null || stereotype.getColor() == null) { + return null; + } + + final File f = createTempFile("plantumlA", ".png"); + final File fEps = createTempFile("plantumlA", ".eps"); + final Color classBorder = rose.getHtmlColor(getSkinParam(), ColorParam.classBorder).getColor(); + final Color classBackground = rose.getHtmlColor(getSkinParam(), ColorParam.classBackground).getColor(); + final Font font = diagram.getSkinParam().getFont(FontParam.CIRCLED_CHARACTER); + final CircledCharacter circledCharacter = new CircledCharacter(stereotype.getCharacter(), getSkinParam() + .getCircledCharacterRadius(), font, stereotype.getColor(), classBorder, Color.BLACK); + return staticFiles.generateCircleCharacter(f, fEps, circledCharacter, classBackground); + // return new DrawFile(f, UGraphicG2d.getSvgString(circledCharacter), + // fEps); + + } + + private ISkinParam getSkinParam() { + return diagram.getSkinParam(); + } + + static public File createTempFile(String prefix, String suffix) throws IOException { + if (suffix.startsWith(".") == false) { + throw new IllegalArgumentException(); + } + final File f = File.createTempFile(prefix, suffix); + Log.info("Creating temporary file: " + f); + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + f.deleteOnExit(); + } + return f; + } + + private String createEps(OutputStream os, List dotStrings) throws IOException, InterruptedException { + + try { + deltaY = 0; + populateImages(); + populateImagesLink(); + final GraphvizMaker dotMaker = createDotMaker(staticFiles.getStaticImages(), + staticFiles.getVisibilityImages(), dotStrings, FileFormat.EPS); + final String dotString = dotMaker.createDotString(); + + if (OptionFlags.getInstance().isKeepTmpFiles()) { + traceDotString(dotString); + } + + // final boolean isUnderline = dotMaker.isUnderline(); + final Graphviz graphviz = GraphvizUtils.create(dotString, "eps"); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + + dotMaker.clean(); + + final boolean isUnderline = dotMaker.isUnderline(); + String eps = new String(baos.toByteArray(), "UTF-8"); + if (isUnderline) { + eps = new UnderlineTrickEps(eps).getString(); + } + + // final Dimension2D dim = getDimensionSvg(svg); + // + // svg = svg + // .replaceFirst( + // "(?i)]*>", + // ""); + // + // svg = addTitleSvg(svg, dim.getWidth(), dim.getHeight()); + // svg = addHeaderSvg(svg, dim.getWidth(), dim.getHeight()); + // svg = addFooterSvg(svg, dim.getWidth(), dim.getHeight()); + // + // // Image management + // final Pattern pImage = Pattern.compile("(?i)]*>"); + // final Matcher mImage = pImage.matcher(svg); + // final StringBuffer sb = new StringBuffer(); + // while (mImage.find()) { + // final String image = mImage.group(0); + // final String href = getValue(image, "href"); + // final double widthSvg = Double.parseDouble(getValuePx(image, + // "width")); + // final double heightSvg = Double.parseDouble(getValuePx(image, + // "height")); + // final double x = Double.parseDouble(getValue(image, "x")); + // final double y = Double.parseDouble(getValue(image, "y")); + // final DrawFile drawFile = getDrawFileFromHref(href); + // final int widthPng = drawFile.getWidthPng(); + // final int heightPng = drawFile.getHeightPng(); + // String svg2 = drawFile.getSvg(); + // final String scale = getScale(widthSvg, heightSvg, widthPng, + // heightPng); + // svg2 = svg2.replaceFirst("<[gG]>", ""); + // mImage.appendReplacement(sb, svg2); + // } + // mImage.appendTail(sb); + // svg = sb.toString(); + + os.write(eps.getBytes("UTF-8")); + + } finally { + // cleanTemporaryFiles(diagram.entities().values()); + // cleanTemporaryFiles(diagram.getLinks()); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java new file mode 100644 index 000000000..8653d4ff0 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java @@ -0,0 +1,182 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4302 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.png.PngSplitter; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; + +public final class CucaDiagramFileMakerBeta { + + private final CucaDiagram diagram; + + public CucaDiagramFileMakerBeta(CucaDiagram diagram) throws IOException { + this.diagram = diagram; + } + + public List createFile(File suggested, List dotStrings, FileFormat fileFormat) throws IOException, + InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggested); + createFile(os, dotStrings, fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + + if (fileFormat == FileFormat.PNG) { + final List result = new PngSplitter(suggested, diagram.getHorizontalPages(), diagram + .getVerticalPages(), diagram.getMetadata()).getFiles(); + for (File f : result) { + Log.info("Creating file: " + f); + } + return result; + } + Log.info("Creating file: " + suggested); + return Arrays.asList(suggested); + } + + public void createFile(OutputStream os, List dotStrings, FileFormat fileFormat) throws IOException, + InterruptedException { + if (fileFormat == FileFormat.PNG) { + createPng(os, dotStrings); + // } else if (fileFormat == FileFormat.SVG) { + // createSvg(os, dotStrings); + // } else if (fileFormat == FileFormat.EPS) { + // createEps(os, dotStrings); + } else { + throw new UnsupportedOperationException(); + } + + } + + private void createPng(OutputStream os, List dotStrings) throws IOException, InterruptedException { + + final Color background = diagram.getSkinParam().getBackgroundColor().getColor(); + EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, background); + BufferedImage im = builder.getBufferedImage(); + Graphics2D g2d = builder.getGraphics2D(); + UGraphicG2d ug = new UGraphicG2d(g2d, im); + final PlayField playField = new PlayField(diagram.getSkinParam()); + + final Collection entities = getFirstLevelEntities(); + System.err.println("entities=" + entities); + // final Collection links = getLinks(entities); + final Collection links = diagram.getLinks(); + + playField.initInternal(entities, links, ug.getStringBounder()); + g2d.dispose(); + + final Dimension2D dim = playField.solve(); + + builder = new EmptyImageBuilder((int) (dim.getWidth() + 1), (int) (dim.getHeight() + 1), background); + im = builder.getBufferedImage(); + g2d = builder.getGraphics2D(); + g2d.translate(10, 0); + ug = new UGraphicG2d(g2d, im); + + playField.drawInternal(ug); + + PngIO.write(im, os); + + } + + // private List getLinks(Collection entities) { + // final List result = new ArrayList(); + // for (Link link : diagram.getLinks()) { + // if (entities.contains(link.getEntity1()) && + // entities.contains(link.getEntity2())) { + // result.add(link); + // } + // } + // return result; + // } + + private Collection getFirstLevelEntities() { + final Collection result = new HashSet(); + diagram.computeAutonomyOfGroups(); + System.err.println("diagramEntities = " + diagram.entities()); + System.err.println("diagramGroups = " + diagram.getGroups()); + addEntitiesOfGroup(result, null); + return result; + } + + private void addEntitiesOfGroup(final Collection result, Group parent) { + System.err.println("addEntitiesOfGroup parent=" + parent); + for (IEntity ent : diagram.entities().values()) { + if (ent.getParent() == parent) { + result.add(ent); + System.err.println("addingA " + ent); + } + } + final Collection groups = parent == null ? diagram.getGroups() : parent.getChildren(); + for (Group g : groups) { + System.err.println("g=" + g + " parent = " + g.getParent()); + if (g.isAutonom() == false) { + addEntitiesOfGroup(result, g); + result.add(g.getEntityCluster()); + System.err.println("addingB " + g.getEntityCluster()); + } else if (g.getParent() == parent) { + assert g.isAutonom(); + assert result.contains(g.getEntityCluster()) == false; + result.add(g.getEntityCluster()); + System.err.println("addingC " + g.getEntityCluster()); + } + + } + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java new file mode 100644 index 000000000..9547820e5 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java @@ -0,0 +1,184 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5047 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.graph.ANode; +import net.sourceforge.plantuml.graph.ANodeImpl; +import net.sourceforge.plantuml.graph.Board; +import net.sourceforge.plantuml.graph.BoardExplorer; +import net.sourceforge.plantuml.graph.Graph2; +import net.sourceforge.plantuml.graph.Heap; +import net.sourceforge.plantuml.graph.Zoda1; +import net.sourceforge.plantuml.graph.Zoda2; +import net.sourceforge.plantuml.png.PngSplitter; + +public final class CucaDiagramPngMaker2 { + + private final CucaDiagram diagram; + + public CucaDiagramPngMaker2(CucaDiagram diagram) { + this.diagram = diagram; + } + + public void createPng(OutputStream os) throws IOException { + final Zoda2 zoda2 = new Zoda2(); + + for (Link link : diagram.getLinks()) { + final String s = link.getEntity1().getCode() + "->" + link.getEntity2().getCode(); + System.err.println("CucaDiagramPngMaker2:: " + s); + final int diffHeight = link.getLength() - 1; + System.err.println("CucaDiagramPngMaker2:: " + s + " " + diffHeight); + zoda2.addLink(s, diffHeight, link); + } + for (Entity ent : diagram.entities().values()) { + ANode n = zoda2.getNode(ent.getCode()); + if (n == null) { + n = zoda2.createAloneNode(ent.getCode()); + } + ((ANodeImpl) n).setUserData(ent); + } + + final List graphs = getGraphs2(zoda2.getHeaps()); + + final Dimension2D totalDim = getTotalDimension(graphs); + final EmptyImageBuilder im = new EmptyImageBuilder((int) totalDim.getWidth(), (int) totalDim.getHeight(), + Color.WHITE); + + double x = 0; + + final Graphics2D g2d = im.getGraphics2D(); + + for (Graph2 g : graphs) { + g2d.setTransform(new AffineTransform()); + g2d.translate(x, 0); + g.draw(g2d); + x += g.getDimension().getWidth(); + } + + ImageIO.write(im.getBufferedImage(), "png", os); + } + + private Dimension2D getTotalDimension(List graphs) { + double width = 0; + double height = 0; + for (Graph2 g : graphs) { + width += g.getDimension().getWidth(); + height = Math.max(height, g.getDimension().getHeight()); + } + return new Dimension2DDouble(width, height); + + } + + private List getGraphs2(Collection heaps) { + final List result = new ArrayList(); + for (Heap h : heaps) { + h.computeRows(); + Board board = new Board(h.getNodes(), h.getLinks()); + + final BoardExplorer boardExplorer = new BoardExplorer(board); + final long start = System.currentTimeMillis(); + for (int i = 0; i < 400; i++) { + final boolean finished = boardExplorer.onePass(); + if (finished) { + break; + } + if (i % 100 == 0) { + Log.info("" + i + " boardExplorer.getBestCost()=" + boardExplorer.getBestCost() + " " + + boardExplorer.collectionSize()); + } + } + Log.info("################# DURATION = " + (System.currentTimeMillis() - start)); + board = boardExplorer.getBestBoard(); + + result.add(new Graph2(board)); + } + return result; + } + + private void createPngOld(OutputStream os) throws IOException { + final Zoda1 zoda1 = new Zoda1(); + if (diagram.getLinks().size() == 0) { + return; + } + for (Link link : diagram.getLinks()) { + final String s = link.getEntity1().getCode() + "->" + link.getEntity2().getCode(); + // System.err.println("CucaDiagramPngMaker2:: " + s); + zoda1.addLink(s); + } + for (Entity ent : diagram.entities().values()) { + final ANodeImpl n = zoda1.getExistingNode(ent.getCode()); + n.setUserData(ent); + } + zoda1.computeRows(); + final Board board = new Board(zoda1.getNodes(), zoda1.getLinks()); + // final BufferedImage im = new Graph2(board).createBufferedImage(); + // ImageIO.write(im, "png", os); + + } + + public List createPng(File pngFile) throws IOException { + OutputStream os = null; + try { + os = new FileOutputStream(pngFile); + createPng(os); + } finally { + if (os != null) { + os.close(); + } + } + + return new PngSplitter(pngFile, diagram.getHorizontalPages(), diagram.getVerticalPages(), diagram.getMetadata()) + .getFiles(); + } +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java new file mode 100644 index 000000000..a0841a53d --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java @@ -0,0 +1,162 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5047 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.graph.ANode; +import net.sourceforge.plantuml.graph.ANodeImpl; +import net.sourceforge.plantuml.graph.Board; +import net.sourceforge.plantuml.graph.BoardExplorer; +import net.sourceforge.plantuml.graph.Graph5; +import net.sourceforge.plantuml.graph.Heap; +import net.sourceforge.plantuml.graph.Zoda2; +import net.sourceforge.plantuml.png.PngSplitter; + +public final class CucaDiagramPngMaker3 { + + private final CucaDiagram diagram; + + public CucaDiagramPngMaker3(CucaDiagram diagram) { + this.diagram = diagram; + } + + public void createPng(OutputStream os) throws IOException { + final Zoda2 zoda2 = new Zoda2(); + + for (Link link : diagram.getLinks()) { + final String s = link.getEntity1().getCode() + "->" + link.getEntity2().getCode(); + // Log.error("CucaDiagramPngMaker3:: " + s); + final int diffHeight = link.getLength() - 1; + // Log.error("CucaDiagramPngMaker3:: " + s + " " + diffHeight); + zoda2.addLink(s, diffHeight, link); + } + for (Entity ent : diagram.entities().values()) { + ANode n = zoda2.getNode(ent.getCode()); + if (n == null) { + n = zoda2.createAloneNode(ent.getCode()); + } + ((ANodeImpl) n).setUserData(ent); + } + + final List graphs = getGraphs3(zoda2.getHeaps()); + + final Dimension2D totalDim = getTotalDimension(graphs); + final EmptyImageBuilder im = new EmptyImageBuilder((int) totalDim.getWidth(), (int) totalDim.getHeight(), + Color.WHITE); + + double x = 0; + + final Graphics2D g2d = im.getGraphics2D(); + + for (Graph5 g : graphs) { + g2d.setTransform(new AffineTransform()); + g2d.translate(x, 0); + g.draw(g2d); + x += g.getDimension().getWidth(); + } + + ImageIO.write(im.getBufferedImage(), "png", os); + } + + private Dimension2D getTotalDimension(List graphs) { + double width = 0; + double height = 0; + for (Graph5 g : graphs) { + width += g.getDimension().getWidth(); + height = Math.max(height, g.getDimension().getHeight()); + } + return new Dimension2DDouble(width, height); + + } + + private List getGraphs3(Collection heaps) { + final List result = new ArrayList(); + for (Heap h : heaps) { + h.computeRows(); + Board board = new Board(h.getNodes(), h.getLinks()); + + final BoardExplorer boardExplorer = new BoardExplorer(board); + final long start = System.currentTimeMillis(); + for (int i = 0; i < 400; i++) { + final boolean finished = boardExplorer.onePass(); + if (finished) { + break; + } + if (i % 100 == 0) { + Log.info("" + i + " boardExplorer.getBestCost()=" + boardExplorer.getBestCost() + " " + + boardExplorer.collectionSize()); + } + } + Log.info("################# DURATION = " + (System.currentTimeMillis() - start)); + board = boardExplorer.getBestBoard(); + + result.add(new Graph5(board)); + } + return result; + } + + public List createPng(File pngFile) throws IOException { + OutputStream os = null; + try { + os = new FileOutputStream(pngFile); + createPng(os); + } finally { + if (os != null) { + os.close(); + } + } + + return new PngSplitter(pngFile, diagram.getHorizontalPages(), diagram.getVerticalPages(), diagram.getMetadata()) + .getFiles(); + } +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java new file mode 100644 index 000000000..40c6380b6 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java @@ -0,0 +1,108 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5378 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; + +public final class CucaDiagramSimplifier { + + private final CucaDiagram diagram; + private final FileFormat fileFormat; + + public CucaDiagramSimplifier(CucaDiagram diagram, List dotStrings, FileFormat fileFormat) throws IOException, + InterruptedException { + this.diagram = diagram; + this.fileFormat = fileFormat; + boolean changed; + do { + changed = false; + final Collection groups = new ArrayList(diagram.getGroups()); + for (Group g : groups) { + if (diagram.isAutarkic(g)) { + final EntityType type; + if (g.getType() == GroupType.CONCURRENT_STATE) { + type = EntityType.STATE_CONCURRENT; + } else if (g.getType() == GroupType.STATE) { + type = EntityType.STATE; + } else if (g.getType() == GroupType.INNER_ACTIVITY) { + type = EntityType.ACTIVITY; + } else if (g.getType() == GroupType.CONCURRENT_ACTIVITY) { + type = EntityType.ACTIVITY_CONCURRENT; + } else { + throw new IllegalStateException(); + } + final Entity proxy = new Entity("#" + g.getCode(), g.getDisplay(), type, g.getParent()); + for (Member field : g.getEntityCluster().fields2()) { + proxy.addField(field); + } + computeImageGroup(g, proxy, dotStrings); + diagram.overideGroup(g, proxy); + changed = true; + } + } + } while (changed); + } + + private void computeImageGroup(final Group group, final Entity entity, List dotStrings) throws IOException, + FileNotFoundException, InterruptedException { + final GroupPngMaker maker = new GroupPngMaker(diagram, group, fileFormat); + final File f = CucaDiagramFileMaker.createTempFile("inner", ".png"); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(f); + maker.createPng(fos, dotStrings); + final String svg = maker.createSvg(dotStrings); + entity.setImageFile(new DrawFile(f, svg)); + } finally { + if (fos != null) { + fos.close(); + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java new file mode 100644 index 000000000..afcf2aa6b --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramTxtMaker.java @@ -0,0 +1,179 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5079 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.posimo.Block; +import net.sourceforge.plantuml.posimo.Cluster; +import net.sourceforge.plantuml.posimo.GraphvizSolverB; +import net.sourceforge.plantuml.posimo.Path; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public final class CucaDiagramTxtMaker { + + private final CucaDiagram diagram; + private final FileFormat fileFormat; + private final UGraphicTxt ug = new UGraphicTxt(); + + private static double getXPixelPerChar() { + return 5; + } + + private static double getYPixelPerChar() { + return 10; + } + + public CucaDiagramTxtMaker(CucaDiagram diagram, FileFormat fileFormat) throws IOException { + this.diagram = diagram; + this.fileFormat = fileFormat; + + final Cluster root = new Cluster(null); + int uid = 0; + + final Map blocks = new HashMap(); + + for (Entity ent : diagram.entities().values()) { + // printClass(ent); + // ug.translate(0, getHeight(ent) + 1); + final double width = getWidth(ent) * getXPixelPerChar(); + final double height = getHeight(ent) * getYPixelPerChar(); + final Block b = new Block(uid++, width, height); + root.addBloc(b); + blocks.put(ent, b); + } + + final GraphvizSolverB solver = new GraphvizSolverB(); + try { + final Collection paths = new ArrayList(); + for (Link link : diagram.getLinks()) { + final Block b1 = blocks.get(link.getEntity1()); + final Block b2 = blocks.get(link.getEntity2()); + paths.add(new Path(b1, b2, null, link.getLength())); + } + final Dimension2D dim = solver.solve(root, paths); + for (Path p : paths) { + ug.setTranslate(0, 0); + p.getDotPath().draw(ug.getCharArea(), getXPixelPerChar(), getYPixelPerChar()); + } + for (Entity ent : diagram.entities().values()) { + final Block b = blocks.get(ent); + final Point2D p = b.getPosition(); + ug.setTranslate(p.getX() / getXPixelPerChar(), p.getY() / getYPixelPerChar()); + printClass(ent); + } + + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + private void printClass(final Entity ent) { + final int w = getWidth(ent); + final int h = getHeight(ent); + ug.getCharArea().drawBoxSimple(0, 0, w, h); + ug.getCharArea().drawStringsLR(StringUtils.getWithNewlines(ent.getDisplay()), 1, 1); + int y = 2; + ug.getCharArea().drawHLine('-', y, 1, w - 1); + y++; + for (Member att : ent.fields2()) { + final List disp = StringUtils.getWithNewlines(att.getDisplayWithVisibilityChar()); + ug.getCharArea().drawStringsLR(disp, 1, y); + y += StringUtils.getHeight(disp); + } + ug.getCharArea().drawHLine('-', y, 1, w - 1); + y++; + for (Member att : ent.methods2()) { + final List disp = StringUtils.getWithNewlines(att.getDisplayWithVisibilityChar()); + ug.getCharArea().drawStringsLR(disp, 1, y); + y += StringUtils.getHeight(disp); + } + } + + public List createFiles(File suggestedFile) throws IOException { + if (fileFormat == FileFormat.UTXT) { + ug.getCharArea().print(new PrintStream(suggestedFile, "UTF-8")); + } else { + ug.getCharArea().print(new PrintStream(suggestedFile)); + } + return Collections.singletonList(suggestedFile); + } + + private int getHeight(Entity entity) { + int result = StringUtils.getHeight(StringUtils.getWithNewlines(entity.getDisplay())); + for (Member att : entity.methods2()) { + result += StringUtils.getHeight(StringUtils.getWithNewlines(att.getDisplayWithVisibilityChar())); + } + for (Member att : entity.fields2()) { + result += StringUtils.getHeight(StringUtils.getWithNewlines(att.getDisplayWithVisibilityChar())); + } + return result + 4; + } + + private int getWidth(Entity entity) { + int result = StringUtils.getWidth(StringUtils.getWithNewlines(entity.getDisplay())); + for (Member att : entity.methods2()) { + final int w = StringUtils.getWidth(StringUtils.getWithNewlines(att.getDisplayWithVisibilityChar())); + if (w > result) { + result = w; + } + } + for (Member att : entity.fields2()) { + final int w = StringUtils.getWidth(StringUtils.getWithNewlines(att.getDisplayWithVisibilityChar())); + if (w > result) { + result = w; + } + } + return result + 2; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java new file mode 100644 index 000000000..2e1ee8a40 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java @@ -0,0 +1,234 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5084 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.EntityPortion; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupHierarchy; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.PortionShower; +import net.sourceforge.plantuml.cucadiagram.Rankdir; +import net.sourceforge.plantuml.skin.VisibilityModifier; + +final public class DotData implements PortionShower { + + final private List links; + final private Map entities; + final private UmlDiagramType umlDiagramType; + final private ISkinParam skinParam; + final private Rankdir rankdir; + final private GroupHierarchy groupHierarchy; + final private Group topParent; + final private PortionShower portionShower; + + final private Map staticImages = new HashMap(); + final private Map visibilityImages = new EnumMap( + VisibilityModifier.class); + + public DotData(Group topParent, List links, Map entities, + UmlDiagramType umlDiagramType, ISkinParam skinParam, Rankdir rankdir, GroupHierarchy groupHierarchy, + PortionShower portionShower) { + this.topParent = topParent; + this.links = links; + this.entities = entities; + this.umlDiagramType = umlDiagramType; + this.skinParam = skinParam; + this.rankdir = rankdir; + this.groupHierarchy = groupHierarchy; + this.portionShower = portionShower; + } + + public DotData(Group topParent, List links, Map entities, + UmlDiagramType umlDiagramType, ISkinParam skinParam, Rankdir rankdir, GroupHierarchy groupHierarchy) { + this(topParent, links, entities, umlDiagramType, skinParam, rankdir, groupHierarchy, new PortionShower() { + public boolean showPortion(EntityPortion portion, IEntity entity) { + return true; + } + }); + } + + public boolean hasUrl() { + return true; + } + + public Map getStaticImages() { + return staticImages; + } + + public void putAllStaticImages(Map staticImages) { + this.staticImages.putAll(staticImages); + } + + public Map getVisibilityImages() { + return visibilityImages; + } + + public void putAllVisibilityImages(Map visibilityImages) { + this.visibilityImages.putAll(visibilityImages); + } + + public UmlDiagramType getUmlDiagramType() { + return umlDiagramType; + } + + public ISkinParam getSkinParam() { + return skinParam; + } + + public Rankdir getRankdir() { + return rankdir; + } + + public GroupHierarchy getGroupHierarchy() { + return groupHierarchy; + } + + public List getLinks() { + return links; + } + + public Map getEntities() { + return entities; + } + + public final Set getAllLinkedTo(final IEntity ent1) { + final Set result = new HashSet(); + result.add(ent1); + int size = 0; + do { + size = result.size(); + for (IEntity ent : entities.values()) { + if (isDirectyLinked(ent, result)) { + result.add(ent); + } + } + } while (size != result.size()); + result.remove(ent1); + return Collections.unmodifiableSet(result); + } + + public final Set getAllLinkedDirectedTo(final IEntity ent1) { + final Set result = new HashSet(); + for (IEntity ent : entities.values()) { + if (isDirectlyLinkedSlow(ent, ent1)) { + result.add(ent); + } + } + return Collections.unmodifiableSet(result); + } + + private boolean isDirectyLinked(IEntity ent1, Collection others) { + for (IEntity ent2 : others) { + if (isDirectlyLinkedSlow(ent1, ent2)) { + return true; + } + } + return false; + } + + private boolean isDirectlyLinkedSlow(IEntity ent1, IEntity ent2) { + for (Link link : links) { + if (link.isBetween(ent1, ent2)) { + return true; + } + } + return false; + } + + public boolean isThereLink(Group g) { + for (Link l : links) { + if (l.getEntity1() == g.getEntityCluster() || l.getEntity2() == g.getEntityCluster()) { + return true; + } + } + return false; + } + + public List getAutoLinks(Group g) { + final List result = new ArrayList(); + for (Link l : links) { + if (l.isAutolink(g)) { + result.add(l); + } + } + return Collections.unmodifiableList(result); + } + + public List getToEdgeLinks(Group g) { + final List result = new ArrayList(); + for (Link l : links) { + if (l.isToEdgeLink(g)) { + result.add(l); + } + } + return Collections.unmodifiableList(result); + } + + public List getFromEdgeLinks(Group g) { + final List result = new ArrayList(); + for (Link l : links) { + if (l.isFromEdgeLink(g)) { + result.add(l); + } + } + return Collections.unmodifiableList(result); + } + + public final Group getTopParent() { + return topParent; + } + + public boolean isEmpty(Group g) { + return groupHierarchy.isEmpty(g); + } + + public boolean showPortion(EntityPortion portion, IEntity entity) { + return portionShower.showPortion(portion, entity); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java new file mode 100644 index 000000000..74ae4ca27 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java @@ -0,0 +1,172 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5396 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Font; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.graphic.FontChange; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.FontStyle; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlCommand; +import net.sourceforge.plantuml.graphic.Splitter; +import net.sourceforge.plantuml.graphic.Text; + +final class DotExpression { + + private final StringBuilder sb = new StringBuilder(); + + private final Font normalFont; + + private FontConfiguration fontConfiguration; + + private final boolean underline; + + private final String fontFamily; + + private final FileFormat fileFormat; + + DotExpression(String html, int defaultFontSize, HtmlColor color, String fontFamily, int style, FileFormat fileFormat) { + this.fontFamily = fontFamily; + this.normalFont = new Font("SansSerif", Font.PLAIN, defaultFontSize); + this.fontConfiguration = new FontConfiguration(normalFont, color.getColor()); + this.fileFormat = fileFormat; + + if ((style & Font.ITALIC) != 0) { + html = "" + html; + } + + if ((style & Font.BOLD) != 0) { + html = "" + html; + } + + html = html.replaceAll(" \\<[uU]\\>", ""); + html = html.replaceAll("\\ ", ""); + underline = html.contains("") || html.contains(""); + final Splitter splitter = new Splitter(html); + for (HtmlCommand command : splitter.getHtmlCommands()) { + if (command instanceof Text) { + manage((Text) command); + } else if (command instanceof FontChange) { + manage((FontChange) command); + } else { + Log.error("Cannot manage " + command); + } + + } + } + + private void manage(FontChange command) { + fontConfiguration = command.apply(fontConfiguration); + } + + private void manage(Text command) { + underline(false); + sb.append(getFontTag()); + + String text = command.getText(); + text = text.replace("<", "<"); + text = text.replace(">", ">"); + text = text.replace("\\n", "
"); + + sb.append(text); + sb.append("
"); + underline(true); + } + + private String getFontTag() { + final int size = fontConfiguration.getFont().getSize(); + final StringBuilder sb = new StringBuilder(""); + return sb.toString(); + } + + private void appendFontWithFamily(final StringBuilder sb) { + String modifier = null; + if (fontConfiguration.containsStyle(FontStyle.ITALIC)) { + modifier = "italic"; + } else if (fontConfiguration.containsStyle(FontStyle.BOLD)) { + modifier = "bold"; + } + appendFace(sb, fontFamily, modifier); + } + + private static void appendFace(StringBuilder sb, String fontFamily, String modifier) { + if (fontFamily == null && modifier == null) { + return; + } + sb.append("FACE=\""); + if (fontFamily != null && modifier != null) { + sb.append(fontFamily + " " + modifier); + } else if (fontFamily != null) { + assert modifier == null; + sb.append(fontFamily); + } else if (modifier != null) { + assert fontFamily == null; + sb.append(modifier); + } else { + assert false; + } + sb.append("\""); + } + + private void underline(boolean closing) { + if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) { + String special = "_"; + if (closing && fileFormat == FileFormat.EPS) { + special = "_!"; + } + sb.append("" + special + ""); + } + } + + public String getDotHtml() { + return sb.toString(); + + } + + boolean isUnderline() { + return underline; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java new file mode 100644 index 000000000..696bf0327 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java @@ -0,0 +1,1563 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5575 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Font; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.SignatureUtils; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityPortion; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.cucadiagram.Rankdir; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.UDrawable; +import net.sourceforge.plantuml.skin.VisibilityModifier; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; + +final public class DotMaker implements GraphvizMaker { + + private final DotData data; + + private static boolean isJunit = false; + + private final List dotStrings; + private boolean underline = false; + private final Rose rose = new Rose(); + + private static String lastDotSignature; + + private final FileFormat fileFormat; + + private final boolean isVisibilityModifierPresent; + + public static void goJunit() { + isJunit = true; + } + + public DotMaker(DotData data, List dotStrings, FileFormat fileFormat) { + this.data = data; + this.dotStrings = dotStrings; + this.fileFormat = fileFormat; + if (data.getSkinParam().classAttributeIconSize() > 0) { + this.isVisibilityModifierPresent = data.getVisibilityImages().size() > 0; + } else { + this.isVisibilityModifierPresent = false; + } + } + + public String createDotString() throws IOException { + + final StringBuilder sb = new StringBuilder(); + + initPrintWriter(sb); + printGroups(sb, null); + printEntities(sb, getUnpackagedEntities()); + printLinks(sb, data.getLinks()); + sb.append("}"); + + // System.err.println(sb); + if (isJunit) { + lastDotSignature = SignatureUtils.getSignatureWithoutImgSrc(sb.toString()); + } + return sb.toString(); + } + + private void initPrintWriter(StringBuilder sb) { + + Log.info("Entities = "+data.getEntities().size()); + final boolean huge = data.getEntities().size()>800; + + sb.append("digraph unix {"); + if (isJunit == false) { + for (String s : dotStrings) { + sb.append(s); + } + } + sb.append("bgcolor=\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\";"); + if (huge) { + sb.append("size=\"400,400;\""); + } else { + sb.append("ratio=auto;"); + } + sb.append("compound=true;"); + sb.append("remincross=true;"); + // sb.append("concentrate=true;"); + sb.append("searchsize=500;"); + if (data.getRankdir() == Rankdir.LEFT_TO_RIGHT) { + sb.append("rankdir=LR;"); + } + } + + + private Collection getUnpackagedEntities() { + final List result = new ArrayList(); + for (IEntity ent : data.getEntities().values()) { + if (ent.getParent() == data.getTopParent()) { + result.add(ent); + } + } + return result; + } + + private void printGroups(StringBuilder sb, Group parent) throws IOException { + for (Group g : data.getGroupHierarchy().getChildrenGroups(parent)) { + if (data.isEmpty(g) && g.getType() == GroupType.PACKAGE) { + final IEntity folder = new Entity(g.getUid(), g.getCode(), g.getDisplay(), EntityType.EMPTY_PACKAGE, + null); + printEntity(sb, folder); + } else { + printGroup(sb, g); + } + } + } + + private void printGroup(StringBuilder sb, Group g) throws IOException { + if (g.getType() == GroupType.CONCURRENT_STATE) { + return; + } + + if (isSpecialGroup(g)) { + printGroupSpecial(sb, g); + } else { + printGroupNormal(sb, g); + } + } + + private void printGroupNormal(StringBuilder sb, Group g) throws IOException { + + sb.append("subgraph " + g.getUid() + " {"); + // sb.append("margin=10;"); + + sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); + final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); + if (fontFamily != null) { + sb.append("fontname=\"" + fontFamily + "\";"); + } + + if (g.getDisplay() != null) { + sb.append("label=<" + manageHtmlIB(g.getDisplay(), getFontParamForGroup()) + ">;"); + } + final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); + sb.append("fontcolor=\"" + fontColor + "\";"); + if (getGroupBackColor(g) != null) { + sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); + } + if (g.getType() == GroupType.STATE) { + sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); + } else { + sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); + } + sb.append("style=\"" + getStyle(g) + "\";"); + + printGroups(sb, g); + + this.printEntities(sb, g.entities().values()); + for (Link link : data.getLinks()) { + eventuallySameRank(sb, g, link); + } + sb.append("}"); + } + + private HtmlColor getGroupBackColor(Group g) { + HtmlColor value = g.getBackColor(); + if (value == null) { + value = data.getSkinParam().getHtmlColor(ColorParam.packageBackground); + // value = rose.getHtmlColor(this.data.getSkinParam(), + // ColorParam.packageBackground); + } + return value; + } + + private void printGroupSpecial(StringBuilder sb, Group g) throws IOException { + + sb.append("subgraph " + g.getUid() + "a {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"a\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + + sb.append("subgraph " + g.getUid() + "v {"); + sb.append("style=solid;"); + // sb.append("margin=10;"); + + final List autolinks = data.getAutoLinks(g); + final List toEdgeLinks = data.getToEdgeLinks(g); + final List fromEdgeLinks = data.getFromEdgeLinks(g); + final boolean autoLabel = autolinks.size() == 1; + + final List nodesHiddenUidOut = getNodesHiddenUidOut(g); + final List nodesHiddenUidIn = getNodesHiddenUidIn(g); + final List nodesHiddenUid = new ArrayList(nodesHiddenUidOut); + nodesHiddenUid.addAll(nodesHiddenUidIn); + for (Link link : nodesHiddenUid) { + final String uid = getHiddenNodeUid(g, link); + // sb.append("subgraph " + g.getUid() + "k" + uid + " {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"k" + uid + "\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + if (OptionFlags.getInstance().isDebugDot()) { + sb.append(uid + ";"); + } else { + sb.append(uid + " [shape=point,width=.01,style=invis,label=\"\"];"); + } + // sb.append("}"); // end of k + } + + for (int j = 1; j < nodesHiddenUidOut.size(); j++) { + for (int i = 0; i < j; i++) { + final Link linki = nodesHiddenUidOut.get(i); + final Link linkj = nodesHiddenUidOut.get(j); + if (linki.getEntity2() != linkj.getEntity2()) { + continue; + } + final String uidi = getHiddenNodeUid(g, linki); + final String uidj = getHiddenNodeUid(g, linkj); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append(uidi + "->" + uidj + ";"); + } else { + sb.append(uidi + "->" + uidj + " [style=invis,arrowtail=none,arrowhead=none];"); + } + + } + } + + if (autoLabel /* || toEdgeLinks.size() > 0 || fromEdgeLinks.size() > 0 */) { + if (OptionFlags.getInstance().isDebugDot()) { + sb.append(g.getUid() + "lmin;"); + sb.append(g.getUid() + "lmax;"); + sb.append(g.getUid() + "lmin->" + g.getUid() + "lmax [minlen=2]; "); + } else { + sb.append(g.getUid() + "lmin [shape=point,width=.01,style=invis,label=\"\"];"); + sb.append(g.getUid() + "lmax [shape=point,width=.01,style=invis,label=\"\"];"); + sb.append(g.getUid() + "lmin->" + g.getUid() + + "lmax [minlen=2,style=invis,arrowtail=none,arrowhead=none]; "); + } + } + // sb.append(g.getUid() + "min->" + g.getUid() + "max;"); + + sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); + final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); + if (fontFamily != null) { + sb.append("fontname=\"" + fontFamily + "\";"); + } + + if (g.getDisplay() != null) { + final StringBuilder label = new StringBuilder(manageHtmlIB(g.getDisplay(), getFontParamForGroup())); + if (g.getEntityCluster().fields2().size() > 0) { + label.append("
"); + for (Member att : g.getEntityCluster().fields2()) { + label.append(manageHtmlIB(" " + att.getDisplayWithVisibilityChar() + " ", + FontParam.STATE_ATTRIBUTE)); + label.append("
"); + } + } + sb.append("label=<" + label + ">;"); + } + + final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); + sb.append("fontcolor=\"" + fontColor + "\";"); + if (getGroupBackColor(g) != null) { + sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); + } + if (g.getType() == GroupType.STATE) { + sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); + } else { + sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); + } + sb.append("style=\"" + getStyle(g) + "\";"); + + sb.append("subgraph " + g.getUid() + "i {"); + sb.append("label=\"i\";"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"i\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + + printGroups(sb, g); + + this.printEntities(sb, g.entities().values()); + for (Link link : data.getLinks()) { + eventuallySameRank(sb, g, link); + } + + for (int i = 0; i < fromEdgeLinks.size(); i++) { + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("eds" + i + ";"); + } else { + sb.append("eds" + i + " [shape=point,width=.01,style=invis,label=\"\"];"); + } + sb.append("eds" + i + " ->" + fromEdgeLinks.get(i).getEntity2().getUid() + + " [minlen=2,style=invis,arrowtail=none,arrowhead=none]; "); + + } + + sb.append("}"); // end of i + sb.append("}"); // end of v + + if (autoLabel) { + sb.append("subgraph " + g.getUid() + "l {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"l\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + final String decorationColor = ",color=" + getColorString(getArrowColorParam()); + + sb.append(g.getUid() + "lab0 [shape=point,width=.01,label=\"\"" + decorationColor + "]"); + String autolabel = autolinks.get(0).getLabel(); + if (autolabel == null) { + autolabel = ""; + } + sb.append(g.getUid() + "lab1 [label=<" + manageHtmlIB(autolabel, getArrowFontParam()) + + ">,shape=plaintext,margin=0];"); + sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lab1 [minlen=0,style=invis];"); + sb.append("}"); // end of l + + sb.append(g.getUid() + "lmin -> " + g.getUid() + "lab0 [ltail=" + g.getUid() + + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); + sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lmax [lhead=" + g.getUid() + + "v,arrowtail=none,arrowhead=open" + decorationColor + "];"); + } + + for (int i = 0; i < fromEdgeLinks.size(); i++) { + sb.append("subgraph " + g.getUid() + "ed" + i + " {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"ed" + i + "\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + final String decorationColor = ",color=" + getColorString(getArrowColorParam()); + String label = fromEdgeLinks.get(i).getLabel(); + if (label == null) { + label = ""; + } + + sb.append(g.getUid() + "fedge" + i + " [shape=point,width=.01,label=\"\"" + decorationColor + "]"); + sb.append("}"); // end of ed + sb.append("eds" + i + " -> " + g.getUid() + "fedge" + i + " [ltail=" + g.getUid() + + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); + sb.append(g.getUid() + "fedge" + i + " -> " + fromEdgeLinks.get(i).getEntity2().getUid() + + "[arrowtail=none,arrowhead=open" + decorationColor); + sb.append(",label=<" + manageHtmlIB(label, getArrowFontParam()) + ">];"); + + } + sb.append("}"); // end of a + } + + private FontParam getFontParamForGroup() { + if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return FontParam.STATE; + } + return FontParam.PACKAGE; + } + + private String getStyle(Group g) { + final StringBuilder sb = new StringBuilder(); + if (g.isBold()) { + sb.append("bold"); + } else if (g.isDashed()) { + sb.append("dashed"); + } else { + sb.append("solid"); + + } + if (getGroupBackColor(g) != null) { + sb.append(",filled"); + } + if (g.isRounded()) { + sb.append(",rounded"); + } + return sb.toString(); + } + + private void printLinks(StringBuilder sb, List links) throws IOException { + for (Link link : appendPhantomLink(links)) { + final IEntity entity1 = link.getEntity1(); + final IEntity entity2 = link.getEntity2(); + if (entity1 == entity2 && entity1.getType() == EntityType.GROUP) { + continue; + } + if (entity1.getType() == EntityType.GROUP && entity2.getParent() == entity1.getParent()) { + continue; + } + if (entity2.getType() == EntityType.GROUP && entity1.getParent() == entity2.getParent()) { + continue; + } + if (entity1.getType() == EntityType.LOLLIPOP || entity2.getType() == EntityType.LOLLIPOP) { + continue; + } + // System.err.println("outing " + link); + printLink(sb, link); + } + } + + private void printLink(StringBuilder sb, Link link) throws IOException { + final StringBuilder decoration = getLinkDecoration(); + + if (link.getWeight() > 1) { + decoration.append("weight=" + link.getWeight() + ","); + } + if (link.getLabeldistance() != null) { + decoration.append("labeldistance=" + link.getLabeldistance() + ","); + } + if (link.getLabelangle() != null) { + decoration.append("labelangle=" + link.getLabelangle() + ","); + } + + final DrawFile noteLink = link.getImageFile(); + + if (link.getLabel() != null) { + decoration.append("label=<" + manageHtmlIB(link.getLabel(), getArrowFontParam()) + ">,"); + } else if (noteLink != null) { + decoration + .append("label=<" + getHtmlForLinkNote(noteLink.getPngOrEps(fileFormat == FileFormat.EPS)) + ">,"); + } + + if (link.getQualifier1() != null) { + decoration.append("taillabel=<" + manageHtmlIB(link.getQualifier1(), getArrowFontParam()) + ">,"); + } + if (link.getQualifier2() != null) { + decoration.append("headlabel=<" + manageHtmlIB(link.getQualifier2(), getArrowFontParam()) + ">,"); + } + decoration.append(link.getType().getSpecificDecoration()); + if (link.isInvis()) { + decoration.append(",style=invis"); + } + + final int len = link.getLength(); + final String lenString = len >= 3 ? ",minlen=" + (len - 1) : ""; + + String uid1 = link.getEntity1().getUid(); + String uid2 = link.getEntity2().getUid(); + if (link.getEntity1().getType() == EntityType.GROUP) { + uid1 = getHiddenNodeUid(link.getEntity1().getParent(), link); + decoration.append(",ltail=" + link.getEntity1().getParent().getUid() + "v"); + } + if (link.getEntity2().getType() == EntityType.GROUP) { + uid2 = getHiddenNodeUid(link.getEntity2().getParent(), link); + decoration.append(",lhead=" + link.getEntity2().getParent().getUid() + "v"); + } + + sb.append(uid1 + " -> " + uid2); + sb.append(decoration); + sb.append(lenString + "];"); + eventuallySameRank(sb, data.getTopParent(), link); + } + + private List getNodesHiddenUidOut(Group g) { + final List result = new ArrayList(); + for (Link link : data.getLinks()) { + if (link.getEntity1().getParent() == link.getEntity2().getParent()) { + continue; + } + if (link.getEntity1().getType() == EntityType.GROUP && link.getEntity1().getParent() == g) { + result.add(link); + } + } + return Collections.unmodifiableList(result); + } + + private List getNodesHiddenUidIn(Group g) { + final List result = new ArrayList(); + for (Link link : data.getLinks()) { + if (link.getEntity1().getParent() == link.getEntity2().getParent()) { + continue; + } + if (link.getEntity2().getType() == EntityType.GROUP && link.getEntity2().getParent() == g) { + result.add(link); + } + } + return Collections.unmodifiableList(result); + } + + private String getHiddenNodeUid(Group g, Link link) { + if (data.isEmpty(g) && g.getType() == GroupType.PACKAGE) { + return g.getUid(); + } + return g.getUid() + "_" + link.getUid(); + } + + private StringBuilder getLinkDecoration() { + final StringBuilder decoration = new StringBuilder("[color=" + getColorString(getArrowColorParam()) + ","); + + decoration.append("fontcolor=" + getFontColorString(getArrowFontParam()) + ","); + decoration.append("fontsize=\"" + data.getSkinParam().getFontSize(getArrowFontParam()) + "\","); + + final String fontName = data.getSkinParam().getFontFamily(getArrowFontParam()); + if (fontName != null) { + decoration.append("fontname=\"" + fontName + "\","); + } + return decoration; + } + + private List appendPhantomLink(List links) { + final List result = new ArrayList(links); + for (Link link : links) { + if (link.getLength() != 1) { + continue; + } + final DrawFile noteLink = link.getImageFile(); + if (noteLink == null) { + continue; + } + final Link phantom = new Link(link.getEntity1(), link.getEntity2(), link.getType(), "", link.getLength()); + phantom.setInvis(true); + result.add(phantom); + } + return result; + } + + private String getHtmlForLinkNote(File image) { + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(image); + final StringBuilder sb = new StringBuilder(""); + sb.append(""); + sb.append("
"); + return sb.toString(); + + } + + private FontParam getArrowFontParam() { + if (data.getUmlDiagramType() == UmlDiagramType.CLASS) { + return FontParam.CLASS_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.OBJECT) { + return FontParam.OBJECT_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.USECASE) { + return FontParam.USECASE_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return FontParam.ACTIVITY_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.COMPONENT) { + return FontParam.COMPONENT_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return FontParam.STATE_ARROW; + } + throw new IllegalStateException(); + } + + private ColorParam getArrowColorParam() { + if (data.getUmlDiagramType() == UmlDiagramType.CLASS) { + return ColorParam.classArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.OBJECT) { + return ColorParam.objectArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.USECASE) { + return ColorParam.usecaseArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return ColorParam.activityArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.COMPONENT) { + return ColorParam.componentArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return ColorParam.stateArrow; + } + throw new IllegalStateException(); + } + + private String getColorString(ColorParam colorParam) { + return "\"" + rose.getHtmlColor(data.getSkinParam(), colorParam).getAsHtml() + "\""; + } + + private String getFontColorString(FontParam fontParam) { + return "\"" + getFontHtmlColor(fontParam).getAsHtml() + "\""; + } + + private HtmlColor getFontHtmlColor(FontParam fontParam) { + return data.getSkinParam().getFontHtmlColor(fontParam); + } + + private void eventuallySameRank(StringBuilder sb, Group entityPackage, Link link) { +// if (workAroundDotBug()) { +// throw new UnsupportedOperationException("workAroundDotBug"); +// // return; +// } + final int len = link.getLength(); + if (len == 1 && link.getEntity1().getParent() == entityPackage + && link.getEntity2().getParent() == entityPackage) { + if (link.getEntity1().getType() == EntityType.GROUP) { + throw new IllegalArgumentException(); + } + if (link.getEntity2().getType() == EntityType.GROUP) { + throw new IllegalArgumentException(); + } + sb.append("{rank=same; " + link.getEntity1().getUid() + "; " + link.getEntity2().getUid() + "}"); + } + } + + private void printEntities(StringBuilder sb, Collection entities) throws IOException { + final Set lollipops = new HashSet(); + final Set lollipopsFriends = new HashSet(); + for (IEntity entity : entities) { + if (entity.getType() == EntityType.LOLLIPOP) { + lollipops.add(entity); + lollipopsFriends.add(getConnectedToLollipop(entity)); + } + } + for (IEntity entity : entities) { + if (lollipops.contains(entity) || lollipopsFriends.contains(entity)) { + continue; + } + printEntity(sb, entity); + } + + for (IEntity ent : lollipopsFriends) { + sb.append("subgraph cluster" + ent.getUid() + "lol {"); + sb.append("style=invis;"); + sb.append("label=\"\";"); + printEntity(sb, ent); + for (IEntity lollipop : getAllLollipop(ent)) { + final Link link = getLinkLollipop(lollipop, ent); + final String headOrTail = getHeadOrTail(lollipop, link); + printEntity(sb, lollipop, headOrTail); + printLink(sb, link); + } + sb.append("}"); + } + + } + + private Collection getAllLollipop(IEntity entity) { + final Collection result = new ArrayList(); + for (IEntity lollipop : data.getAllLinkedDirectedTo(entity)) { + if (lollipop.getType() == EntityType.LOLLIPOP) { + result.add(lollipop); + } + } + return result; + } + + private IEntity getConnectedToLollipop(IEntity lollipop) { + assert lollipop.getType() == EntityType.LOLLIPOP; + final Collection linked = data.getAllLinkedDirectedTo(lollipop); + if (linked.size() != 1) { + throw new IllegalStateException("size=" + linked.size()); + } + return linked.iterator().next(); + } + + private Link getLinkLollipop(IEntity lollipop, IEntity ent) { + assert lollipop.getType() == EntityType.LOLLIPOP; + for (Link link : data.getLinks()) { + if (link.isBetween(lollipop, ent)) { + return link; + } + } + throw new IllegalArgumentException(); + } + + private void printEntity(StringBuilder sb, IEntity entity, String headOrTail) throws IOException { + final EntityType type = entity.getType(); + if (type == EntityType.LOLLIPOP) { + final String color1 = getColorString(ColorParam.classBackground); + final String color2 = getColorString(ColorParam.classBorder); + final String colorBack = getColorString(ColorParam.background); + final String labelLo = manageHtmlIB(entity.getDisplay(), FontParam.CLASS_ATTRIBUTE); + sb.append(entity.getUid() + " [fillcolor=" + color1 + ",color=" + color2 + ",style=\"filled\"," + + "shape=circle,width=0.12,height=0.12,label=\"\"];"); + sb.append(entity.getUid() + " -> " + entity.getUid() + "[color=" + colorBack + + ",arrowtail=none,arrowhead=none," + headOrTail + "=<" + labelLo + ">];"); + } else { + throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); + } + + } + + private void printEntity(StringBuilder sb, IEntity entity) throws IOException { + final EntityType type = entity.getType(); + final String label = getLabel(entity); + if (type == EntityType.GROUP) { + return; + } + if (type == EntityType.ABSTRACT_CLASS || type == EntityType.CLASS || type == EntityType.INTERFACE + || type == EntityType.ENUM) { + String dec = " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" + + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) + + ",style=filled,shape=box," + label; + if (this.data.hasUrl() && entity.getUrl() != null) { + dec += ",URL=\"" + entity.getUrl() + "\""; + } + dec += "];"; + sb.append(entity.getUid() + dec); + } else if (type == EntityType.OBJECT) { + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" + + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) + + ",style=filled,shape=record," + label + "];"); + } else if (type == EntityType.USECASE) { + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE) + ",fillcolor=" + + getColorString(ColorParam.usecaseBackground) + ",color=" + + getColorString(ColorParam.usecaseBorder) + ",style=filled," + label + "];"); + } else if (type == EntityType.ACTOR) { + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE_ACTOR) + + ",margin=0,shape=plaintext," + label + "];"); + } else if (type == EntityType.CIRCLE_INTERFACE) { + sb.append(entity.getUid() + " [margin=0,shape=plaintext," + label + "];"); + } else if (type == EntityType.COMPONENT) { + sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.COMPONENT) + + ",fillcolor=" + getColorString(ColorParam.componentBackground) + ",color=" + + getColorString(ColorParam.componentBorder) + ",style=filled,shape=component," + label + "];"); + } else if (type == EntityType.NOTE) { + final DrawFile file = entity.getImageFile(); + if (file == null) { + // sb.append(entity.getUid() + ";"); + // Log.error("Warning : no file for NOTE"); + // return; + throw new IllegalStateException("No file for NOTE"); + } + if (file.getPngOrEps(fileFormat == FileFormat.EPS).exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file + .getPngOrEps(fileFormat == FileFormat.EPS)); + sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",shape=none,image=\"" + absolutePath + "\"];"); + } else if (type == EntityType.ACTIVITY) { + String shape = "octagon"; + if (entity.getImageFile() != null) { + shape = "rect"; + } + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.ACTIVITY) + ",fillcolor=" + + getColorString(ColorParam.activityBackground) + ",color=" + + getColorString(ColorParam.activityBorder) + ",style=\"rounded,filled\",shape=" + shape + "," + + label + "];"); + } else if (type == EntityType.BRANCH) { + sb.append(entity.getUid() + " [fillcolor=" + getColorString(ColorParam.activityBackground) + ",color=" + + getColorString(ColorParam.activityBorder) + + ",style=\"filled\",shape=diamond,height=.25,width=.25,label=\"\"];"); + // if (StringUtils.isNotEmpty(entity.getDisplay())) { + // sb.append(entity.getUid() + "->" + entity.getUid() + + // "[taillabel=\"" + entity.getDisplay() + // + "\",arrowtail=none,arrowhead=none,color=\"white\"];"); + // } + } else if (type == EntityType.SYNCHRO_BAR) { + final String color = getColorString(ColorParam.activityBar); + sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + + "shape=rect,height=.08,width=1.30,label=\"\"];"); + } else if (type == EntityType.CIRCLE_START) { + final String color = getColorString(ColorParam.activityStart); + sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + + "shape=circle,width=.20,height=.20,label=\"\"];"); + } else if (type == EntityType.CIRCLE_END) { + final String color = getColorString(ColorParam.activityEnd); + sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + + "shape=doublecircle,width=.13,height=.13,label=\"\"];"); + } else if (type == EntityType.POINT_FOR_ASSOCIATION) { + sb.append(entity.getUid() + " [width=.05,shape=point,color=" + getColorString(ColorParam.classBorder) + + "];"); + } else if (type == EntityType.STATE) { + sb.append(entity.getUid() + " [color=" + getColorString(ColorParam.stateBorder) + + ",shape=record,style=\"rounded,filled\",color=" + getColorString(ColorParam.stateBorder)); + if (entity.getImageFile() == null) { + sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); + } else { + sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); + // sb.append(",fillcolor=\"" + + // data.getSkinParam().getBackgroundColor().getAsHtml() + "\""); + } + sb.append("," + label + "];"); + } else if (type == EntityType.STATE_CONCURRENT) { + final DrawFile file = entity.getImageFile(); + if (file == null) { + throw new IllegalStateException(); + } + if (file.getPng().exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file.getPng()); + sb.append(entity.getUid() + " [margin=1,pad=1," + label + ",style=dashed,shape=box,image=\"" + absolutePath + + "\"];"); + } else if (type == EntityType.ACTIVITY_CONCURRENT) { + final DrawFile file = entity.getImageFile(); + if (file == null) { + throw new IllegalStateException(); + } + if (file.getPng().exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file.getPng()); + sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",style=dashed,shape=box,image=\"" + absolutePath + + "\"];"); + } else if (type == EntityType.EMPTY_PACKAGE) { + sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.PACKAGE) + + ",fillcolor=" + getColorString(ColorParam.packageBackground) + ",color=" + + getColorString(ColorParam.packageBorder) + ",style=filled,shape=tab," + label + "];"); + } else { + throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); + } + } + + private String getHeadOrTail(IEntity lollipop, Link link) { + assert lollipop.getType() == EntityType.LOLLIPOP; + if (link.getLength() > 1 && link.getEntity1() == lollipop) { + return "taillabel"; + } + return "headlabel"; + } + + private String getLabel(IEntity entity) throws IOException { + if (entity.getType() == EntityType.ABSTRACT_CLASS || entity.getType() == EntityType.CLASS + || entity.getType() == EntityType.INTERFACE || entity.getType() == EntityType.ENUM) { + return "label=" + getLabelForClassOrInterfaceOrEnum(entity); + } else if (entity.getType() == EntityType.LOLLIPOP) { + return "label=" + getLabelForLollipop(entity); + } else if (entity.getType() == EntityType.OBJECT) { + return "label=" + getLabelForObject(entity); + } else if (entity.getType() == EntityType.ACTOR) { + return "label=" + getLabelForActor(entity); + } else if (entity.getType() == EntityType.CIRCLE_INTERFACE) { + return "label=" + getLabelForCircleInterface(entity); + } else if (entity.getType() == EntityType.NOTE) { + return "label=\"\""; + } else if (entity.getType() == EntityType.STATE_CONCURRENT) { + return "label=\"\""; + } else if (entity.getType() == EntityType.ACTIVITY_CONCURRENT) { + return "label=\"\""; + } else if (entity.getType() == EntityType.COMPONENT) { + return "label=" + getLabelForComponent(entity); + } else if (entity.getType() == EntityType.ACTIVITY) { + final DrawFile drawFile = entity.getImageFile(); + if (drawFile != null) { + final String path = StringUtils.getPlateformDependentAbsolutePath(drawFile.getPng()); + final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; + final StringBuilder sb = new StringBuilder("label=<"); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append("
"); + sb.append("
"); + sb.append(">"); + return sb.toString(); + } + return "label=" + getSimpleLabelAsHtml(entity, FontParam.ACTIVITY); + } else if (entity.getType() == EntityType.EMPTY_PACKAGE) { + return "label=" + getSimpleLabelAsHtml(entity, getFontParamForGroup()); + } else if (entity.getType() == EntityType.USECASE) { + return "label=" + getLabelForUsecase(entity); + } else if (entity.getType() == EntityType.STATE) { + return "label=" + getLabelForState(entity); + } + return "label=\"" + entity.getDisplay() + "\""; + } + + private String getSimpleLabelAsHtml(IEntity entity, FontParam param) { + return "<" + manageHtmlIB(entity.getDisplay(), param) + ">"; + } + + private String getLabelForState(IEntity entity) throws IOException { + final DrawFile cFile = entity.getImageFile(); + final String stateBgcolor = getColorString(ColorParam.stateBackground); + + final StringBuilder sb = new StringBuilder("<{"); + sb.append(""); + sb.append("
" + manageHtmlIB(entity.getDisplay(), FontParam.STATE) + "
"); + + if (entity.fields2().size() > 0) { + sb.append("|"); + for (Member att : entity.fields2()) { + sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.STATE_ATTRIBUTE)); + sb.append("
"); + } + } + + if (cFile != null) { + sb.append("|"); + final String path = StringUtils.getPlateformDependentAbsolutePath(cFile.getPng()); + final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; + + sb.append(""); + sb.append(""); + sb.append(""); + sb.append("
"); + sb.append("
"); + } + + if (entity.fields2().size() == 0 && cFile == null) { + sb.append("|"); + } + + sb.append("}>"); + + return sb.toString(); + } + + private String getLabelForUsecase(IEntity entity) { + final Stereotype stereotype = getStereotype(entity); + if (stereotype == null) { + return getSimpleLabelAsHtml(entity, FontParam.USECASE); + } + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE) + "
>"); + return sb.toString(); + } + + private String getLabelForComponent(IEntity entity) { + final Stereotype stereotype = getStereotype(entity); + if (stereotype == null) { + return getSimpleLabelAsHtml(entity, FontParam.COMPONENT); + } + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
>"); + return sb.toString(); + } + + private String getLabelForActor(IEntity entity) throws IOException { + final String actorAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages().get( + EntityType.ACTOR).getPngOrEps(fileFormat == FileFormat.EPS)); + final Stereotype stereotype = getStereotype(entity); + + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_ACTOR_STEREOTYPE) + + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE_ACTOR) + "
>"); + return sb.toString(); + + } + + private String getLabelForCircleInterface(IEntity entity) throws IOException { + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() + .get(EntityType.CIRCLE_INTERFACE).getPngOrEps(fileFormat == FileFormat.EPS)); + final Stereotype stereotype = getStereotype(entity); + + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
>"); + return sb.toString(); + + } + + private String getLabelForLollipop(IEntity entity) throws IOException { + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() + .get(EntityType.LOLLIPOP).getPngOrEps(fileFormat == FileFormat.EPS)); + final Stereotype stereotype = getStereotype(entity); + + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.CLASS) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.CLASS) + "
>"); + return sb.toString(); + + } + + private String getLabelForClassOrInterfaceOrEnum(IEntity entity) throws IOException { + if (isVisibilityModifierPresent) { + return getLabelForClassOrInterfaceOrEnumWithVisibilityImage(entity); + } + return getLabelForClassOrInterfaceOrEnumOld(entity); + + } + + private String getLabelForClassOrInterfaceOrEnumOld(IEntity entity) throws IOException { + DrawFile cFile = entity.getImageFile(); + if (cFile == null) { + cFile = data.getStaticImages().get(entity.getType()); + } + if (cFile == null) { + throw new IllegalStateException(); + } + final String circleAbsolutePath; + if (data.showPortion(EntityPortion.CIRCLED_CHARACTER, entity)) { + circleAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(cFile + .getPngOrEps(fileFormat == FileFormat.EPS)); + } else { + circleAbsolutePath = null; + } + + final StringBuilder sb = new StringBuilder("<"); + + final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); + final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); + + if (showFields == false && showMethods == false) { + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); + } else { + sb.append(""); + sb.append(""); + + if (showFields) { + // if (fileFormat == FileFormat.EPS) { + // sb.append(addFieldsEps(entity.fields2(), true)); + // } else { + final boolean hasStatic = hasStatic(entity.fields2()); + sb.append(""); + // } + } + if (showMethods) { + // if (fileFormat == FileFormat.EPS) { + // sb.append(addFieldsEps(entity.methods2(), true)); + // } else { + final boolean hasStatic = hasStatic(entity.methods2()); + sb.append(""); + // } + } + sb.append("
"); + final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, longuestFieldOrAttribute, 30); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, spring, true, 0)); + + sb.append("
"); + for (Member att : entity.fields2()) { + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, + getColorString(ColorParam.classBackground), true)); + sb.append("
"); + } + sb.append("
"); + for (Member att : entity.methods2()) { + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, + getColorString(ColorParam.classBackground), true)); + sb.append("
"); + } + sb.append("
"); + } + sb.append(">"); + + return sb.toString(); + } + + final private List fileToClean = new ArrayList(); + + private String addFieldsEps(List members, boolean withVisibilityChar) throws IOException { + final List texts = new ArrayList(); + for (Member att : members) { + String s = att.getDisplay(withVisibilityChar); + if (att.isAbstract()) { + s = "" + s + ""; + } + if (att.isStatic()) { + s = "" + s + ""; + } + texts.add(s); + } + final Font font = data.getSkinParam().getFont(FontParam.CLASS_ATTRIBUTE); + final Color color = getFontHtmlColor(FontParam.CLASS_ATTRIBUTE).getColor(); + final TextBlock text = TextBlockUtils.create(texts, font, color, HorizontalAlignement.LEFT); + final File feps = CucaDiagramFileMaker.createTempFile("member", ".eps"); + UGraphicEps.copyEpsToFile(new UDrawable() { + public void drawU(UGraphic ug) { + text.drawU(ug, 0, 0); + } + }, feps); + fileToClean.add(feps); + + final String path = StringUtils.getPlateformDependentAbsolutePath(feps); + + return "" + "" + + "" + "" + "
" + "
"; + // return "toto"; + } + + private boolean hasStatic(Collection attributes) { + for (Member att : attributes) { + if (att.isStatic()) { + return true; + } + } + return false; + } + + private String getLabelForClassOrInterfaceOrEnumWithVisibilityImage(IEntity entity) throws IOException { + DrawFile cFile = entity.getImageFile(); + if (cFile == null) { + cFile = data.getStaticImages().get(entity.getType()); + } + if (cFile == null) { + throw new IllegalStateException(); + } + final String circleAbsolutePath; + if (data.showPortion(EntityPortion.CIRCLED_CHARACTER, entity)) { + circleAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(cFile + .getPngOrEps(fileFormat == FileFormat.EPS)); + } else { + circleAbsolutePath = null; + } + + final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); + final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); + + final StringBuilder sb = new StringBuilder("<"); + if (showFields == false && showMethods == false) { + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); + } else { + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); + final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, + getLongestMethods(entity)), 30); + final int springMethod = computeSpring(getLongestMethods(entity), Math.max(longuestHeader, + getLongestField(entity)), 30); + + sb.append(""); + sb.append(""); + + if (showFields) { + sb.append(""); + } + if (showMethods) { + sb.append(""); + } + sb.append("
"); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, spring, true, 0)); + sb.append("
"); + if (entity.fields2().size() > 0) { + buildTableVisibility(entity, true, sb, springField); + } + sb.append("
"); + if (entity.methods2().size() > 0) { + buildTableVisibility(entity, false, sb, springMethod); + } + sb.append("
"); + } + sb.append(">"); + + return sb.toString(); + + } + + private int computeSpring(final int current, final int maximum, int maxSpring) { + if (maximum <= current) { + return 0; + } + final int spring = maximum - current; + if (spring > maxSpring) { + return maxSpring; + } + return spring; + } + + private void buildTableVisibility(IEntity entity, boolean isField, final StringBuilder sb, int spring) + throws IOException { + sb.append(""); + + final boolean hasStatic = hasStatic(entity.methods2()); + for (Member att : isField ? entity.fields2() : entity.methods2()) { + sb.append(""); + for (int i = 0; i < spring; i++) { + sb.append(""); + } + sb.append(""); + } + sb.append("
"); + String s = att.getDisplayWithVisibilityChar(); + final VisibilityModifier visibilityModifier = VisibilityModifier + .getVisibilityModifier(s.charAt(0), isField); + if (visibilityModifier != null) { + final String modifierFile = StringUtils.getPlateformDependentAbsolutePath(data.getVisibilityImages() + .get(visibilityModifier).getPngOrEps(fileFormat == FileFormat.EPS)); + sb.append(""); + s = s.substring(1); + } + sb.append(""); + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, + getColorString(ColorParam.classBackground), false)); + // sb.append(manageHtmlIB(s, FontParam.CLASS_ATTRIBUTE)); + sb.append("
"); + } + + private int getLonguestHeader(IEntity entity) { + int result = entity.getDisplay().length(); + final Stereotype stereotype = getStereotype(entity); + if (isThereLabel(stereotype)) { + final int size = stereotype.getLabel().length(); + if (size > result) { + result = size; + } + } + return result; + } + + private int getLongestFieldOrAttribute(IEntity entity) { + return Math.max(getLongestField(entity), getLongestMethods(entity)); + } + + private int getLongestMethods(IEntity entity) { + int result = 0; + for (Member att : entity.methods2()) { + final int size = att.getDisplayWithVisibilityChar().length(); + if (size > result) { + result = size; + } + } + return result; + + } + + private int getLongestField(IEntity entity) { + int result = 0; + for (Member att : entity.fields2()) { + final int size = att.getDisplayWithVisibilityChar().length(); + if (size > result) { + result = size; + } + } + return result; + } + + private String getLabelForObject(IEntity entity) throws IOException { + if (isVisibilityModifierPresent) { + return getLabelForObjectWithVisibilityImage(entity); + } + return getLabelForObjectOld(entity); + } + + private String getLabelForObjectWithVisibilityImage(IEntity entity) throws IOException { + + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); + final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, + getLongestMethods(entity)), 30); + + final StringBuilder sb = new StringBuilder("<"); + sb.append(""); + sb.append(""); + sb.append("
"); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); + + sb.append("
"); + + if (entity.fields2().size() == 0) { + sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); + } else { + buildTableVisibility(entity, true, sb, springField); + } + + sb.append("
>"); + + return sb.toString(); + + } + + private String getLabelForObjectOld(IEntity entity) throws IOException { + final StringBuilder sb = new StringBuilder("<"); + sb.append(""); + sb.append(""); + sb.append("
"); + + final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, longuestFieldOrAttribute, 30); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); + + sb.append("
"); + + if (entity.fields2().size() == 0) { + sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); + } else { + for (Member att : entity.fields2()) { + sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.OBJECT_ATTRIBUTE)); + sb.append("
"); + } + } + + sb.append("
>"); + + return sb.toString(); + } + + private String manageHtmlIB(String s, FontParam param) { + s = unicode(s); + final int fontSize = data.getSkinParam().getFontSize(param); + final int style = data.getSkinParam().getFontStyle(param); + final String fontFamily = data.getSkinParam().getFontFamily(param); + final DotExpression dotExpression = new DotExpression(s, fontSize, getFontHtmlColor(param), fontFamily, style, + fileFormat); + final String result = dotExpression.getDotHtml(); + if (dotExpression.isUnderline()) { + underline = true; + } + return result; + } + + private String manageHtmlIBspecial(Member att, FontParam param, boolean hasStatic, String backColor, + boolean withVisibilityChar) { + String prefix = ""; + if (hasStatic) { + prefix = "_"; + } + if (att.isAbstract()) { + return prefix + manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); + } + if (att.isStatic()) { + return manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); + } + return prefix + manageHtmlIB(att.getDisplay(withVisibilityChar), param); + } + + private String manageSpace(int size) { + final DotExpression dotExpression = new DotExpression(" ", size, new HtmlColor("white"), null, Font.PLAIN, + fileFormat); + final String result = dotExpression.getDotHtml(); + return result; + } + + static String unicode(String s) { + final StringBuilder result = new StringBuilder(); + for (char c : s.toCharArray()) { + if (c > 127 || c == '&') { + final int i = c; + result.append("&#" + i + ";"); + } else { + result.append(c); + } + } + return result.toString(); + } + + private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(IEntity entity, + final String circleAbsolutePath, int cellSpacing, boolean classes) { + final StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append(""); + if (circleAbsolutePath == null) { + sb.append(""); + sb.append("
"); + } else { + sb.append(""); + sb.append(""); + } + + appendLabelAndStereotype(entity, sb, classes); + sb.append("
"); + return sb.toString(); + } + + private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(IEntity entity, final String circleAbsolutePath, + int spring, boolean classes, int border) throws IOException { + if (spring == 0) { + return getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(entity, circleAbsolutePath, 0, classes); + } + final StringBuilder sb = new StringBuilder(); + + sb + .append(""); + sb.append(""); + + for (int i = 0; i < spring; i++) { + sb.append(""); + } + + if (circleAbsolutePath != null) { + if (circleAbsolutePath.endsWith(".png")) { + final BufferedImage im = ImageIO.read(new File(circleAbsolutePath)); + final int height = im.getHeight(); + final int width = im.getWidth(); + sb.append(""); + } else if (circleAbsolutePath.endsWith(".eps")) { + sb.append(""); + } + } + + sb.append(""); + + for (int i = 0; i < spring; i++) { + sb.append(""); + } + sb.append("
"); + appendLabelAndStereotype(entity, sb, classes); + sb.append("
"); + return sb.toString(); + } + + private void appendLabelAndStereotype(IEntity entity, final StringBuilder sb, boolean classes) { + final Stereotype stereotype = getStereotype(entity); + if (isThereLabel(stereotype)) { + sb.append("
"); + sb.append(manageHtmlIB(stereotype.getLabel(), classes ? FontParam.CLASS_STEREOTYPE + : FontParam.OBJECT_STEREOTYPE)); + sb.append("
"); + } + String display = entity.getDisplay(); + final boolean italic = entity.getType() == EntityType.ABSTRACT_CLASS + || entity.getType() == EntityType.INTERFACE; + if (italic) { + display = "" + display; + } + sb.append(manageHtmlIB(display, classes ? FontParam.CLASS : FontParam.OBJECT)); + } + + private String getHtmlHeaderTableForClassOrInterfaceOrEnumNew(Entity entity, final String circleAbsolutePath) { + final StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append("
"); + + appendLabelAndStereotype(entity, sb, true); + sb.append("
"); + return sb.toString(); + } + + private boolean isThereLabel(final Stereotype stereotype) { + return stereotype != null && stereotype.getLabel() != null; + } + + private Stereotype getStereotype(IEntity entity) { + if (data.showPortion(EntityPortion.STEREOTYPE, entity) == false) { + return null; + } + return entity.getStereotype(); + } + + public final boolean isUnderline() { + return underline; + } + + private boolean workAroundDotBug() { + for (Link link : data.getLinks()) { + if (link.getLength() != 1) { + return false; + } + } + if (data.getUmlDiagramType() == UmlDiagramType.CLASS && allEntitiesAreClasses(data.getEntities().values())) { + return true; + } + for (IEntity ent : data.getEntities().values()) { + if (data.getAllLinkedTo(ent).size() == 0) { + return true; + } + } + return false; + } + + private boolean allEntitiesAreClasses(Collection entities) { + for (IEntity ent : entities) { + if (ent.getType() != EntityType.CLASS && ent.getType() != EntityType.ABSTRACT_CLASS + && ent.getType() != EntityType.INTERFACE && ent.getType() != EntityType.ENUM) { + return false; + } + } + return true; + } + + private boolean isSpecialGroup(Group g) { + if (g.getType() == GroupType.STATE) { + return true; + } + if (g.getType() == GroupType.CONCURRENT_STATE) { + throw new IllegalStateException(); + } + if (data.isThereLink(g)) { + return true; + } + return false; + } + + public static final String getLastDotSignature() { + return lastDotSignature; + } + + public static final void reset() { + lastDotSignature = null; + } + + public void clean() { + if (OptionFlags.getInstance().isKeepTmpFiles()) { + return; + } + for (File f : fileToClean) { + Log.info("Deleting temporary file " + f); + final boolean ok = f.delete(); + if (ok == false) { + Log.error("Cannot delete: " + f); + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker2.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker2.java new file mode 100644 index 000000000..51fa95412 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker2.java @@ -0,0 +1,1498 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5383 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Font; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.SignatureUtils; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityPortion; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.cucadiagram.Rankdir; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.skin.VisibilityModifier; +import net.sourceforge.plantuml.skin.rose.Rose; + +final public class DotMaker2 implements GraphvizMaker { + + private final DotData data; + + private static boolean isJunit = false; + + private final List dotStrings; + private boolean underline = false; + private final Rose rose = new Rose(); + + private static String lastDotSignature; + + private final FileFormat fileFormat; + + private final boolean isVisibilityModifierPresent; + + public static void goJunit() { + isJunit = true; + } + + public DotMaker2(DotData data, List dotStrings, FileFormat fileFormat) { + this.data = data; + this.dotStrings = dotStrings; + this.fileFormat = fileFormat; + if (data.getSkinParam().classAttributeIconSize() > 0) { + this.isVisibilityModifierPresent = data.getVisibilityImages().size() > 0; + } else { + this.isVisibilityModifierPresent = false; + } + } + + public String createDotString() throws IOException { + + final StringBuilder sb = new StringBuilder(); + + initPrintWriter(sb); + printGroups(sb, null); + printEntities(sb, getUnpackagedEntities()); + printLinks(sb, data.getLinks()); + sb.append("}"); + + // System.err.println(sb); + if (isJunit) { + lastDotSignature = SignatureUtils.getSignatureWithoutImgSrc(sb.toString()); + } + return sb.toString(); + } + + private void initPrintWriter(StringBuilder sb) { + + sb.append("digraph unix {"); + if (isJunit == false) { + for (String s : dotStrings) { + sb.append(s); + } + } + sb.append("bgcolor=\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\";"); + sb.append("ratio=auto;"); + sb.append("compound=true;"); + sb.append("remincross=true;"); + // sb.append("concentrate=true;"); + // pw.println("size=\"40,40;\""); + sb.append("searchsize=500;"); + if (data.getRankdir() == Rankdir.LEFT_TO_RIGHT) { + sb.append("rankdir=LR;"); + } + } + + private Collection getUnpackagedEntities() { + final List result = new ArrayList(); + for (IEntity ent : data.getEntities().values()) { + if (ent.getParent() == data.getTopParent()) { + result.add(ent); + } + } + return result; + } + + private void printGroups(StringBuilder sb, Group parent) throws IOException { + for (Group g : data.getGroupHierarchy().getChildrenGroups(parent)) { + if (data.isEmpty(g) && g.getType() == GroupType.PACKAGE) { + final IEntity folder = new Entity(g.getUid(), g.getCode(), g.getDisplay(), EntityType.EMPTY_PACKAGE, + null); + printEntity(sb, folder); + } else { + printGroup(sb, g); + } + } + } + + private void printGroup(StringBuilder sb, Group g) throws IOException { + if (g.getType() == GroupType.CONCURRENT_STATE) { + return; + } + + if (isSpecialGroup(g)) { + printGroupSpecial(sb, g); + } else { + printGroupNormal(sb, g); + } + } + + private void printGroupNormal(StringBuilder sb, Group g) throws IOException { + + sb.append("subgraph " + g.getUid() + " {"); + // sb.append("margin=10;"); + + sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); + final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); + if (fontFamily != null) { + sb.append("fontname=\"" + fontFamily + "\";"); + } + + if (g.getDisplay() != null) { + sb.append("label=<" + manageHtmlIB(g.getDisplay(), getFontParamForGroup()) + ">;"); + } + final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); + sb.append("fontcolor=\"" + fontColor + "\";"); + if (getGroupBackColor(g) != null) { + sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); + } + if (g.getType() == GroupType.STATE) { + sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); + } else { + sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); + } + sb.append("style=\"" + getStyle(g) + "\";"); + + printGroups(sb, g); + + this.printEntities(sb, g.entities().values()); + for (Link link : data.getLinks()) { + eventuallySameRank(sb, g, link); + } + sb.append("}"); + } + + private HtmlColor getGroupBackColor(Group g) { + HtmlColor value = g.getBackColor(); + if (value == null) { + value = data.getSkinParam().getHtmlColor(ColorParam.packageBackground); + // value = rose.getHtmlColor(this.data.getSkinParam(), + // ColorParam.packageBackground); + } + return value; + } + + private void printGroupSpecial(StringBuilder sb, Group g) throws IOException { + + sb.append("subgraph " + g.getUid() + "a {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"a\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + + sb.append("subgraph " + g.getUid() + "v {"); + sb.append("style=solid;"); + // sb.append("margin=10;"); + + final List autolinks = data.getAutoLinks(g); + final List toEdgeLinks = data.getToEdgeLinks(g); + final List fromEdgeLinks = data.getFromEdgeLinks(g); + final boolean autoLabel = autolinks.size() == 1; + + final List nodesHiddenUidOut = getNodesHiddenUidOut(g); + final List nodesHiddenUidIn = getNodesHiddenUidIn(g); + final List nodesHiddenUid = new ArrayList(nodesHiddenUidOut); + nodesHiddenUid.addAll(nodesHiddenUidIn); + for (Link link : nodesHiddenUid) { + final String uid = getHiddenNodeUid(g, link); + // sb.append("subgraph " + g.getUid() + "k" + uid + " {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"k" + uid + "\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + if (OptionFlags.getInstance().isDebugDot()) { + sb.append(uid + ";"); + } else { + sb.append(uid + " [shape=point,width=.01,style=invis,label=\"\"];"); + } + // sb.append("}"); // end of k + } + + for (int j = 1; j < nodesHiddenUidOut.size(); j++) { + for (int i = 0; i < j; i++) { + final Link linki = nodesHiddenUidOut.get(i); + final Link linkj = nodesHiddenUidOut.get(j); + if (linki.getEntity2() != linkj.getEntity2()) { + continue; + } + final String uidi = getHiddenNodeUid(g, linki); + final String uidj = getHiddenNodeUid(g, linkj); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append(uidi + "->" + uidj + ";"); + } else { + sb.append(uidi + "->" + uidj + " [style=invis,arrowtail=none,arrowhead=none];"); + } + + } + } + + if (autoLabel /* || toEdgeLinks.size() > 0 || fromEdgeLinks.size() > 0 */) { + if (OptionFlags.getInstance().isDebugDot()) { + sb.append(g.getUid() + "lmin;"); + sb.append(g.getUid() + "lmax;"); + sb.append(g.getUid() + "lmin->" + g.getUid() + "lmax [minlen=2]; "); + } else { + sb.append(g.getUid() + "lmin [shape=point,width=.01,style=invis,label=\"\"];"); + sb.append(g.getUid() + "lmax [shape=point,width=.01,style=invis,label=\"\"];"); + sb.append(g.getUid() + "lmin->" + g.getUid() + + "lmax [minlen=2,style=invis,arrowtail=none,arrowhead=none]; "); + } + } + // sb.append(g.getUid() + "min->" + g.getUid() + "max;"); + + sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); + final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); + if (fontFamily != null) { + sb.append("fontname=\"" + fontFamily + "\";"); + } + + if (g.getDisplay() != null) { + final StringBuilder label = new StringBuilder(manageHtmlIB(g.getDisplay(), getFontParamForGroup())); + if (g.getEntityCluster().fields2().size() > 0) { + label.append("
"); + for (Member att : g.getEntityCluster().fields2()) { + label.append(manageHtmlIB(" " + att.getDisplayWithVisibilityChar() + " ", + FontParam.STATE_ATTRIBUTE)); + label.append("
"); + } + } + sb.append("label=<" + label + ">;"); + } + + final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); + sb.append("fontcolor=\"" + fontColor + "\";"); + if (getGroupBackColor(g) != null) { + sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); + } + if (g.getType() == GroupType.STATE) { + sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); + } else { + sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); + } + sb.append("style=\"" + getStyle(g) + "\";"); + + sb.append("subgraph " + g.getUid() + "i {"); + sb.append("label=\"i\";"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"i\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + + printGroups(sb, g); + + this.printEntities(sb, g.entities().values()); + for (Link link : data.getLinks()) { + eventuallySameRank(sb, g, link); + } + + for (int i = 0; i < fromEdgeLinks.size(); i++) { + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("eds" + i + ";"); + } else { + sb.append("eds" + i + " [shape=point,width=.01,style=invis,label=\"\"];"); + } + sb.append("eds" + i + " ->" + fromEdgeLinks.get(i).getEntity2().getUid() + + " [minlen=2,style=invis,arrowtail=none,arrowhead=none]; "); + + } + + sb.append("}"); // end of i + sb.append("}"); // end of v + + if (autoLabel) { + sb.append("subgraph " + g.getUid() + "l {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"l\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + final String decorationColor = ",color=" + getColorString(getArrowColorParam()); + + sb.append(g.getUid() + "lab0 [shape=point,width=.01,label=\"\"" + decorationColor + "]"); + String autolabel = autolinks.get(0).getLabel(); + if (autolabel == null) { + autolabel = ""; + } + sb.append(g.getUid() + "lab1 [label=<" + manageHtmlIB(autolabel, getArrowFontParam()) + + ">,shape=plaintext,margin=0];"); + sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lab1 [minlen=0,style=invis];"); + sb.append("}"); // end of l + + sb.append(g.getUid() + "lmin -> " + g.getUid() + "lab0 [ltail=" + g.getUid() + + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); + sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lmax [lhead=" + g.getUid() + + "v,arrowtail=none,arrowhead=open" + decorationColor + "];"); + } + + for (int i = 0; i < fromEdgeLinks.size(); i++) { + sb.append("subgraph " + g.getUid() + "ed" + i + " {"); + if (OptionFlags.getInstance().isDebugDot()) { + sb.append("style=dotted;"); + sb.append("label=\"ed" + i + "\";"); + } else { + sb.append("style=invis;"); + sb.append("label=\"\";"); + } + final String decorationColor = ",color=" + getColorString(getArrowColorParam()); + String label = fromEdgeLinks.get(i).getLabel(); + if (label == null) { + label = ""; + } + + sb.append(g.getUid() + "fedge" + i + " [shape=point,width=.01,label=\"\"" + decorationColor + "]"); + sb.append("}"); // end of ed + sb.append("eds" + i + " -> " + g.getUid() + "fedge" + i + " [ltail=" + g.getUid() + + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); + sb.append(g.getUid() + "fedge" + i + " -> " + fromEdgeLinks.get(i).getEntity2().getUid() + + "[arrowtail=none,arrowhead=open" + decorationColor); + sb.append(",label=<" + manageHtmlIB(label, getArrowFontParam()) + ">];"); + + } + sb.append("}"); // end of a + } + + private FontParam getFontParamForGroup() { + if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return FontParam.STATE; + } + return FontParam.PACKAGE; + } + + private String getStyle(Group g) { + final StringBuilder sb = new StringBuilder(); + if (g.isBold()) { + sb.append("bold"); + } else if (g.isDashed()) { + sb.append("dashed"); + } else { + sb.append("solid"); + + } + if (getGroupBackColor(g) != null) { + sb.append(",filled"); + } + if (g.isRounded()) { + sb.append(",rounded"); + } + return sb.toString(); + } + + private void printLinks(StringBuilder sb, List links) throws IOException { + for (Link link : appendPhantomLink(links)) { + final IEntity entity1 = link.getEntity1(); + final IEntity entity2 = link.getEntity2(); + if (entity1 == entity2 && entity1.getType() == EntityType.GROUP) { + continue; + } + if (entity1.getType() == EntityType.GROUP && entity2.getParent() == entity1.getParent()) { + continue; + } + if (entity2.getType() == EntityType.GROUP && entity1.getParent() == entity2.getParent()) { + continue; + } + if (entity1.getType() == EntityType.LOLLIPOP || entity2.getType() == EntityType.LOLLIPOP) { + continue; + } + // System.err.println("outing " + link); + printLink(sb, link); + } + } + + private void printLink(StringBuilder sb, Link link) throws IOException { + final StringBuilder decoration = getLinkDecoration(); + + if (link.getWeight() > 1) { + decoration.append("weight=" + link.getWeight() + ","); + } + if (link.getLabeldistance() != null) { + decoration.append("labeldistance=" + link.getLabeldistance() + ","); + } + if (link.getLabelangle() != null) { + decoration.append("labelangle=" + link.getLabelangle() + ","); + } + + final DrawFile noteLink = link.getImageFile(); + + if (link.getLabel() != null) { + decoration.append("label=<" + manageHtmlIB(link.getLabel(), getArrowFontParam()) + ">,"); + } else if (noteLink != null) { + decoration + .append("label=<" + getHtmlForLinkNote(noteLink.getPngOrEps(fileFormat == FileFormat.EPS)) + ">,"); + } + + if (link.getQualifier1() != null) { + decoration.append("taillabel=<" + manageHtmlIB(link.getQualifier1(), getArrowFontParam()) + ">,"); + } + if (link.getQualifier2() != null) { + decoration.append("headlabel=<" + manageHtmlIB(link.getQualifier2(), getArrowFontParam()) + ">,"); + } + decoration.append(link.getType().getSpecificDecoration()); + if (link.isInvis()) { + decoration.append(",style=invis"); + } + + final int len = link.getLength(); + final String lenString = len >= 3 ? ",minlen=" + (len - 1) : ""; + + String uid1 = link.getEntity1().getUid(); + String uid2 = link.getEntity2().getUid(); + if (link.getEntity1().getType() == EntityType.GROUP) { + uid1 = getHiddenNodeUid(link.getEntity1().getParent(), link); + decoration.append(",ltail=" + link.getEntity1().getParent().getUid() + "v"); + } + if (link.getEntity2().getType() == EntityType.GROUP) { + uid2 = getHiddenNodeUid(link.getEntity2().getParent(), link); + decoration.append(",lhead=" + link.getEntity2().getParent().getUid() + "v"); + } + + sb.append(uid1 + " -> " + uid2); + sb.append(decoration); + sb.append(lenString + "];"); + eventuallySameRank(sb, data.getTopParent(), link); + } + + private List getNodesHiddenUidOut(Group g) { + final List result = new ArrayList(); + for (Link link : data.getLinks()) { + if (link.getEntity1().getParent() == link.getEntity2().getParent()) { + continue; + } + if (link.getEntity1().getType() == EntityType.GROUP && link.getEntity1().getParent() == g) { + result.add(link); + } + } + return Collections.unmodifiableList(result); + } + + private List getNodesHiddenUidIn(Group g) { + final List result = new ArrayList(); + for (Link link : data.getLinks()) { + if (link.getEntity1().getParent() == link.getEntity2().getParent()) { + continue; + } + if (link.getEntity2().getType() == EntityType.GROUP && link.getEntity2().getParent() == g) { + result.add(link); + } + } + return Collections.unmodifiableList(result); + } + + private String getHiddenNodeUid(Group g, Link link) { + if (data.isEmpty(g) && g.getType() == GroupType.PACKAGE) { + return g.getUid(); + } + return g.getUid() + "_" + link.getUid(); + } + + private StringBuilder getLinkDecoration() { + final StringBuilder decoration = new StringBuilder("[color=" + getColorString(getArrowColorParam()) + ","); + + decoration.append("fontcolor=" + getFontColorString(getArrowFontParam()) + ","); + decoration.append("fontsize=\"" + data.getSkinParam().getFontSize(getArrowFontParam()) + "\","); + + final String fontName = data.getSkinParam().getFontFamily(getArrowFontParam()); + if (fontName != null) { + decoration.append("fontname=\"" + fontName + "\","); + } + return decoration; + } + + private List appendPhantomLink(List links) { + final List result = new ArrayList(links); + for (Link link : links) { + if (link.getLength() != 1) { + continue; + } + final DrawFile noteLink = link.getImageFile(); + if (noteLink == null) { + continue; + } + final Link phantom = new Link(link.getEntity1(), link.getEntity2(), link.getType(), "", link.getLength()); + phantom.setInvis(true); + result.add(phantom); + } + return result; + } + + private String getHtmlForLinkNote(File image) { + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(image); + final StringBuilder sb = new StringBuilder(""); + sb.append(""); + sb.append("
"); + return sb.toString(); + + } + + private FontParam getArrowFontParam() { + if (data.getUmlDiagramType() == UmlDiagramType.CLASS) { + return FontParam.CLASS_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.OBJECT) { + return FontParam.OBJECT_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.USECASE) { + return FontParam.USECASE_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return FontParam.ACTIVITY_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.COMPONENT) { + return FontParam.COMPONENT_ARROW; + } else if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return FontParam.STATE_ARROW; + } + throw new IllegalStateException(); + } + + private ColorParam getArrowColorParam() { + if (data.getUmlDiagramType() == UmlDiagramType.CLASS) { + return ColorParam.classArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.OBJECT) { + return ColorParam.objectArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.USECASE) { + return ColorParam.usecaseArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return ColorParam.activityArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.COMPONENT) { + return ColorParam.componentArrow; + } else if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return ColorParam.stateArrow; + } + throw new IllegalStateException(); + } + + private String getColorString(ColorParam colorParam) { + return "\"" + rose.getHtmlColor(data.getSkinParam(), colorParam).getAsHtml() + "\""; + } + + private String getFontColorString(FontParam fontParam) { + return "\"" + getFontHtmlColor(fontParam).getAsHtml() + "\""; + } + + private HtmlColor getFontHtmlColor(FontParam fontParam) { + return data.getSkinParam().getFontHtmlColor(fontParam); + } + + private void eventuallySameRank(StringBuilder sb, Group entityPackage, Link link) { + if (workAroundDotBug()) { + return; + } + final int len = link.getLength(); + if (len == 1 && link.getEntity1().getParent() == entityPackage + && link.getEntity2().getParent() == entityPackage) { + if (link.getEntity1().getType() == EntityType.GROUP) { + throw new IllegalArgumentException(); + } + if (link.getEntity2().getType() == EntityType.GROUP) { + throw new IllegalArgumentException(); + } + sb.append("{rank=same; " + link.getEntity1().getUid() + "; " + link.getEntity2().getUid() + "}"); + } + } + + private void printEntities(StringBuilder sb, Collection entities) throws IOException { + final Set lollipops = new HashSet(); + final Set lollipopsFriends = new HashSet(); + for (IEntity entity : entities) { + if (entity.getType() == EntityType.LOLLIPOP) { + lollipops.add(entity); + lollipopsFriends.add(getConnectedToLollipop(entity)); + } + } + for (IEntity entity : entities) { + if (lollipops.contains(entity) || lollipopsFriends.contains(entity)) { + continue; + } + printEntity(sb, entity); + } + + for (IEntity ent : lollipopsFriends) { + sb.append("subgraph cluster" + ent.getUid() + "lol {"); + sb.append("style=invis;"); + sb.append("label=\"\";"); + printEntity(sb, ent); + for (IEntity lollipop : getAllLollipop(ent)) { + final Link link = getLinkLollipop(lollipop, ent); + final String headOrTail = getHeadOrTail(lollipop, link); + printEntity(sb, lollipop, headOrTail); + printLink(sb, link); + } + sb.append("}"); + } + + } + + private Collection getAllLollipop(IEntity entity) { + final Collection result = new ArrayList(); + for (IEntity lollipop : data.getAllLinkedDirectedTo(entity)) { + if (lollipop.getType() == EntityType.LOLLIPOP) { + result.add(lollipop); + } + } + return result; + } + + private IEntity getConnectedToLollipop(IEntity lollipop) { + assert lollipop.getType() == EntityType.LOLLIPOP; + final Collection linked = data.getAllLinkedDirectedTo(lollipop); + if (linked.size() != 1) { + throw new IllegalStateException("size=" + linked.size()); + } + return linked.iterator().next(); + } + + private Link getLinkLollipop(IEntity lollipop, IEntity ent) { + assert lollipop.getType() == EntityType.LOLLIPOP; + for (Link link : data.getLinks()) { + if (link.isBetween(lollipop, ent)) { + return link; + } + } + throw new IllegalArgumentException(); + } + + private void printEntity(StringBuilder sb, IEntity entity, String headOrTail) throws IOException { + final EntityType type = entity.getType(); + if (type == EntityType.LOLLIPOP) { + final String color1 = getColorString(ColorParam.classBackground); + final String color2 = getColorString(ColorParam.classBorder); + final String colorBack = getColorString(ColorParam.background); + final String labelLo = manageHtmlIB(entity.getDisplay(), FontParam.CLASS_ATTRIBUTE); + sb.append(entity.getUid() + " [fillcolor=" + color1 + ",color=" + color2 + ",style=\"filled\"," + + "shape=circle,width=0.12,height=0.12,label=\"\"];"); + sb.append(entity.getUid() + " -> " + entity.getUid() + "[color=" + colorBack + + ",arrowtail=none,arrowhead=none," + headOrTail + "=<" + labelLo + ">];"); + } else { + throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); + } + + } + + private void printEntity(StringBuilder sb, IEntity entity) throws IOException { + final EntityType type = entity.getType(); + final String label = getLabel(entity); + if (type == EntityType.GROUP) { + return; + } + if (type == EntityType.ABSTRACT_CLASS || type == EntityType.CLASS || type == EntityType.INTERFACE + || type == EntityType.ENUM) { + String dec = " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" + + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) + + ",style=filled,shape=box," + label; + if (this.data.hasUrl() && entity.getUrl() != null) { + dec += ",URL=\"" + entity.getUrl() + "\""; + } + dec += "];"; + sb.append(entity.getUid() + dec); + } else if (type == EntityType.OBJECT) { + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" + + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) + + ",style=filled,shape=record," + label + "];"); + } else if (type == EntityType.USECASE) { + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE) + ",fillcolor=" + + getColorString(ColorParam.usecaseBackground) + ",color=" + + getColorString(ColorParam.usecaseBorder) + ",style=filled," + label + "];"); + } else if (type == EntityType.ACTOR) { + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE_ACTOR) + + ",margin=0,shape=plaintext," + label + "];"); + } else if (type == EntityType.CIRCLE_INTERFACE) { + sb.append(entity.getUid() + " [margin=0,shape=plaintext," + label + "];"); + } else if (type == EntityType.COMPONENT) { + sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.COMPONENT) + + ",fillcolor=" + getColorString(ColorParam.componentBackground) + ",color=" + + getColorString(ColorParam.componentBorder) + ",style=filled,shape=component," + label + "];"); + } else if (type == EntityType.NOTE) { + final DrawFile file = entity.getImageFile(); + if (file == null) { + // sb.append(entity.getUid() + ";"); + // Log.error("Warning : no file for NOTE"); + // return; + throw new IllegalStateException("No file for NOTE"); + } + if (file.getPngOrEps(fileFormat == FileFormat.EPS).exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file + .getPngOrEps(fileFormat == FileFormat.EPS)); + sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",shape=none,image=\"" + absolutePath + "\"];"); + } else if (type == EntityType.ACTIVITY) { + String shape = "octagon"; + if (entity.getImageFile() != null) { + shape = "rect"; + } + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.ACTIVITY) + ",fillcolor=" + + getColorString(ColorParam.activityBackground) + ",color=" + + getColorString(ColorParam.activityBorder) + ",style=\"rounded,filled\",shape=" + shape + "," + + label + "];"); + } else if (type == EntityType.BRANCH) { + sb.append(entity.getUid() + " [fillcolor=" + getColorString(ColorParam.activityBackground) + ",color=" + + getColorString(ColorParam.activityBorder) + + ",style=\"filled\",shape=diamond,height=.25,width=.25,label=\"\"];"); + // if (StringUtils.isNotEmpty(entity.getDisplay())) { + // sb.append(entity.getUid() + "->" + entity.getUid() + + // "[taillabel=\"" + entity.getDisplay() + // + "\",arrowtail=none,arrowhead=none,color=\"white\"];"); + // } + } else if (type == EntityType.SYNCHRO_BAR) { + final String color = getColorString(ColorParam.activityBar); + sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + + "shape=rect,height=.08,width=1.30,label=\"\"];"); + } else if (type == EntityType.CIRCLE_START) { + final String color = getColorString(ColorParam.activityStart); + sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + + "shape=circle,width=.20,label=\"\"];"); + } else if (type == EntityType.CIRCLE_END) { + final String color = getColorString(ColorParam.activityEnd); + sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + + "shape=doublecircle,width=.13,label=\"\"];"); + } else if (type == EntityType.POINT_FOR_ASSOCIATION) { + sb.append(entity.getUid() + " [width=.05,shape=point,color=" + getColorString(ColorParam.classBorder) + + "];"); + } else if (type == EntityType.STATE) { + sb.append(entity.getUid() + " [color=" + getColorString(ColorParam.stateBorder) + + ",shape=record,style=\"rounded,filled\",color=" + getColorString(ColorParam.stateBorder)); + if (entity.getImageFile() == null) { + sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); + } else { + sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); + // sb.append(",fillcolor=\"" + + // data.getSkinParam().getBackgroundColor().getAsHtml() + "\""); + } + sb.append("," + label + "];"); + } else if (type == EntityType.STATE_CONCURRENT) { + final DrawFile file = entity.getImageFile(); + if (file == null) { + throw new IllegalStateException(); + } + if (file.getPng().exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file.getPng()); + sb.append(entity.getUid() + " [margin=1,pad=1," + label + ",style=dashed,shape=box,image=\"" + absolutePath + + "\"];"); + } else if (type == EntityType.ACTIVITY_CONCURRENT) { + final DrawFile file = entity.getImageFile(); + if (file == null) { + throw new IllegalStateException(); + } + if (file.getPng().exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file.getPng()); + sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",style=dashed,shape=box,image=\"" + absolutePath + + "\"];"); + } else if (type == EntityType.EMPTY_PACKAGE) { + sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.PACKAGE) + + ",fillcolor=" + getColorString(ColorParam.packageBackground) + ",color=" + + getColorString(ColorParam.packageBorder) + ",style=filled,shape=tab," + label + "];"); + } else { + throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); + } + } + + private String getHeadOrTail(IEntity lollipop, Link link) { + assert lollipop.getType() == EntityType.LOLLIPOP; + if (link.getLength() > 1 && link.getEntity1() == lollipop) { + return "taillabel"; + } + return "headlabel"; + } + + private String getLabel(IEntity entity) throws IOException { + if (entity.getType() == EntityType.ABSTRACT_CLASS || entity.getType() == EntityType.CLASS + || entity.getType() == EntityType.INTERFACE || entity.getType() == EntityType.ENUM) { + return "label=" + getLabelForClassOrInterfaceOrEnum(entity); + } else if (entity.getType() == EntityType.LOLLIPOP) { + return "label=" + getLabelForLollipop(entity); + } else if (entity.getType() == EntityType.OBJECT) { + return "label=" + getLabelForObject(entity); + } else if (entity.getType() == EntityType.ACTOR) { + return "label=" + getLabelForActor(entity); + } else if (entity.getType() == EntityType.CIRCLE_INTERFACE) { + return "label=" + getLabelForCircleInterface(entity); + } else if (entity.getType() == EntityType.NOTE) { + return "label=\"\""; + } else if (entity.getType() == EntityType.STATE_CONCURRENT) { + return "label=\"\""; + } else if (entity.getType() == EntityType.ACTIVITY_CONCURRENT) { + return "label=\"\""; + } else if (entity.getType() == EntityType.COMPONENT) { + return "label=" + getLabelForComponent(entity); + } else if (entity.getType() == EntityType.ACTIVITY) { + final DrawFile drawFile = entity.getImageFile(); + if (drawFile != null) { + final String path = StringUtils.getPlateformDependentAbsolutePath(drawFile.getPng()); + final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; + final StringBuilder sb = new StringBuilder("label=<"); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append("
"); + sb.append("
"); + sb.append(">"); + return sb.toString(); + } + return "label=" + getSimpleLabelAsHtml(entity, FontParam.ACTIVITY); + } else if (entity.getType() == EntityType.EMPTY_PACKAGE) { + return "label=" + getSimpleLabelAsHtml(entity, getFontParamForGroup()); + } else if (entity.getType() == EntityType.USECASE) { + return "label=" + getLabelForUsecase(entity); + } else if (entity.getType() == EntityType.STATE) { + return "label=" + getLabelForState(entity); + } + return "label=\"" + entity.getDisplay() + "\""; + } + + private String getSimpleLabelAsHtml(IEntity entity, FontParam param) { + return "<" + manageHtmlIB(entity.getDisplay(), param) + ">"; + } + + private String getLabelForState(IEntity entity) throws IOException { + final DrawFile cFile = entity.getImageFile(); + final String stateBgcolor = getColorString(ColorParam.stateBackground); + + final StringBuilder sb = new StringBuilder("<{"); + sb.append(""); + sb.append("
" + manageHtmlIB(entity.getDisplay(), FontParam.STATE) + "
"); + + if (entity.fields2().size() > 0) { + sb.append("|"); + for (Member att : entity.fields2()) { + sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.STATE_ATTRIBUTE)); + sb.append("
"); + } + } + + if (cFile != null) { + sb.append("|"); + final String path = StringUtils.getPlateformDependentAbsolutePath(cFile.getPng()); + final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; + + sb.append(""); + sb.append(""); + sb.append(""); + sb.append("
"); + sb.append("
"); + } + + if (entity.fields2().size() == 0 && cFile == null) { + sb.append("|"); + } + + sb.append("}>"); + + return sb.toString(); + } + + private String getLabelForUsecase(IEntity entity) { + final Stereotype stereotype = getStereotype(entity); + if (stereotype == null) { + return getSimpleLabelAsHtml(entity, FontParam.USECASE); + } + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE) + "
>"); + return sb.toString(); + } + + private String getLabelForComponent(IEntity entity) { + final Stereotype stereotype = getStereotype(entity); + if (stereotype == null) { + return getSimpleLabelAsHtml(entity, FontParam.COMPONENT); + } + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
>"); + return sb.toString(); + } + + private String getLabelForActor(IEntity entity) throws IOException { + final String actorAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages().get( + EntityType.ACTOR).getPngOrEps(fileFormat == FileFormat.EPS)); + final Stereotype stereotype = getStereotype(entity); + + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_ACTOR_STEREOTYPE) + + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE_ACTOR) + "
>"); + return sb.toString(); + + } + + private String getLabelForCircleInterface(IEntity entity) throws IOException { + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() + .get(EntityType.CIRCLE_INTERFACE).getPngOrEps(fileFormat == FileFormat.EPS)); + final Stereotype stereotype = getStereotype(entity); + + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
>"); + return sb.toString(); + + } + + private String getLabelForLollipop(IEntity entity) throws IOException { + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() + .get(EntityType.LOLLIPOP).getPngOrEps(fileFormat == FileFormat.EPS)); + final Stereotype stereotype = getStereotype(entity); + + final StringBuilder sb = new StringBuilder("<"); + if (isThereLabel(stereotype)) { + sb.append(""); + } + sb.append(""); + sb.append(""); + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.CLASS) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.CLASS) + "
>"); + return sb.toString(); + + } + + private String getLabelForClassOrInterfaceOrEnum(IEntity entity) throws IOException { + if (isVisibilityModifierPresent) { + return getLabelForClassOrInterfaceOrEnumWithVisibilityImage(entity); + } + return getLabelForClassOrInterfaceOrEnumOld(entity); + + } + + private String getLabelForClassOrInterfaceOrEnumOld(IEntity entity) throws IOException { + DrawFile cFile = entity.getImageFile(); + if (cFile == null) { + cFile = data.getStaticImages().get(entity.getType()); + } + if (cFile == null) { + throw new IllegalStateException(); + } + final String circleAbsolutePath; + if (data.showPortion(EntityPortion.CIRCLED_CHARACTER, entity)) { + circleAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(cFile + .getPngOrEps(fileFormat == FileFormat.EPS)); + } else { + circleAbsolutePath = null; + } + + final StringBuilder sb = new StringBuilder("<"); + + final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); + final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); + + if (showFields == false && showMethods == false) { + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); + } else { + sb.append(""); + sb.append(""); + + if (showFields) { + final boolean hasStatic = hasStatic(entity.fields2()); + sb.append(""); + } + if (showMethods) { + final boolean hasStatic = hasStatic(entity.methods2()); + sb.append(""); + } + + sb.append("
"); + final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, longuestFieldOrAttribute, 30); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, spring, true, 0)); + + sb.append("
"); + for (Member att : entity.fields2()) { + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, + getColorString(ColorParam.classBackground), true)); + sb.append("
"); + } + sb.append("
"); + for (Member att : entity.methods2()) { + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, + getColorString(ColorParam.classBackground), true)); + sb.append("
"); + } + sb.append("
"); + } + sb.append(">"); + + return sb.toString(); + } + + private boolean hasStatic(Collection attributes) { + for (Member att : attributes) { + if (att.isStatic()) { + return true; + } + } + return false; + } + + private String getLabelForClassOrInterfaceOrEnumWithVisibilityImage(IEntity entity) throws IOException { + DrawFile cFile = entity.getImageFile(); + if (cFile == null) { + cFile = data.getStaticImages().get(entity.getType()); + } + if (cFile == null) { + throw new IllegalStateException(); + } + final String circleAbsolutePath; + if (data.showPortion(EntityPortion.CIRCLED_CHARACTER, entity)) { + circleAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(cFile + .getPngOrEps(fileFormat == FileFormat.EPS)); + } else { + circleAbsolutePath = null; + } + + final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); + final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); + + final StringBuilder sb = new StringBuilder("<"); + if (showFields == false && showMethods == false) { + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); + } else { + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); + final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, + getLongestMethods(entity)), 30); + final int springMethod = computeSpring(getLongestMethods(entity), Math.max(longuestHeader, + getLongestField(entity)), 30); + + sb.append(""); + sb.append(""); + + if (showFields) { + sb.append(""); + } + if (showMethods) { + sb.append(""); + } + sb.append("
"); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, spring, true, 0)); + sb.append("
"); + if (entity.fields2().size() > 0) { + buildTableVisibility(entity, true, sb, springField); + } + sb.append("
"); + if (entity.methods2().size() > 0) { + buildTableVisibility(entity, false, sb, springMethod); + } + sb.append("
"); + } + sb.append(">"); + + return sb.toString(); + + } + + private int computeSpring(final int current, final int maximum, int maxSpring) { + if (maximum <= current) { + return 0; + } + final int spring = maximum - current; + if (spring > maxSpring) { + return maxSpring; + } + return spring; + } + + private void buildTableVisibility(IEntity entity, boolean isField, final StringBuilder sb, int spring) + throws IOException { + sb.append(""); + + final boolean hasStatic = hasStatic(entity.methods2()); + for (Member att : isField ? entity.fields2() : entity.methods2()) { + sb.append(""); + for (int i = 0; i < spring; i++) { + sb.append(""); + } + sb.append(""); + } + sb.append("
"); + String s = att.getDisplayWithVisibilityChar(); + final VisibilityModifier visibilityModifier = VisibilityModifier + .getVisibilityModifier(s.charAt(0), isField); + if (visibilityModifier != null) { + final String modifierFile = StringUtils.getPlateformDependentAbsolutePath(data.getVisibilityImages() + .get(visibilityModifier).getPngOrEps(fileFormat == FileFormat.EPS)); + sb.append(""); + s = s.substring(1); + } + sb.append(""); + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, + getColorString(ColorParam.classBackground), false)); + // sb.append(manageHtmlIB(s, FontParam.CLASS_ATTRIBUTE)); + sb.append("
"); + } + + private int getLonguestHeader(IEntity entity) { + int result = entity.getDisplay().length(); + final Stereotype stereotype = getStereotype(entity); + if (isThereLabel(stereotype)) { + final int size = stereotype.getLabel().length(); + if (size > result) { + result = size; + } + } + return result; + } + + private int getLongestFieldOrAttribute(IEntity entity) { + return Math.max(getLongestField(entity), getLongestMethods(entity)); + } + + private int getLongestMethods(IEntity entity) { + int result = 0; + for (Member att : entity.methods2()) { + final int size = att.getDisplayWithVisibilityChar().length(); + if (size > result) { + result = size; + } + } + return result; + + } + + private int getLongestField(IEntity entity) { + int result = 0; + for (Member att : entity.fields2()) { + final int size = att.getDisplayWithVisibilityChar().length(); + if (size > result) { + result = size; + } + } + return result; + } + + private String getLabelForObject(IEntity entity) throws IOException { + if (isVisibilityModifierPresent) { + return getLabelForObjectWithVisibilityImage(entity); + } + return getLabelForObjectOld(entity); + } + + private String getLabelForObjectWithVisibilityImage(IEntity entity) throws IOException { + + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); + final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, + getLongestMethods(entity)), 30); + + final StringBuilder sb = new StringBuilder("<"); + sb.append(""); + sb.append(""); + sb.append("
"); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); + + sb.append("
"); + + if (entity.fields2().size() == 0) { + sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); + } else { + buildTableVisibility(entity, true, sb, springField); + } + + sb.append("
>"); + + return sb.toString(); + + } + + private String getLabelForObjectOld(IEntity entity) throws IOException { + final StringBuilder sb = new StringBuilder("<"); + sb.append(""); + sb.append(""); + sb.append("
"); + + final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); + final int longuestHeader = getLonguestHeader(entity); + final int spring = computeSpring(longuestHeader, longuestFieldOrAttribute, 30); + + sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); + + sb.append("
"); + + if (entity.fields2().size() == 0) { + sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); + } else { + for (Member att : entity.fields2()) { + sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.OBJECT_ATTRIBUTE)); + sb.append("
"); + } + } + + sb.append("
>"); + + return sb.toString(); + } + + private String manageHtmlIB(String s, FontParam param) { + s = unicode(s); + final int fontSize = data.getSkinParam().getFontSize(param); + final int style = data.getSkinParam().getFontStyle(param); + final String fontFamily = data.getSkinParam().getFontFamily(param); + final DotExpression dotExpression = new DotExpression(s, fontSize, getFontHtmlColor(param), fontFamily, style, + fileFormat); + final String result = dotExpression.getDotHtml(); + if (dotExpression.isUnderline()) { + underline = true; + } + return result; + } + + private String manageHtmlIBspecial(Member att, FontParam param, boolean hasStatic, String backColor, boolean withVisibilityChar) { + String prefix = ""; + if (hasStatic) { + prefix = "_"; + } + if (att.isAbstract()) { + return prefix + manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); + } + if (att.isStatic()) { + return manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); + } + return prefix + manageHtmlIB(att.getDisplay(withVisibilityChar), param); + } + + private String manageSpace(int size) { + final DotExpression dotExpression = new DotExpression(" ", size, new HtmlColor("white"), null, Font.PLAIN, + fileFormat); + final String result = dotExpression.getDotHtml(); + return result; + } + + static String unicode(String s) { + final StringBuilder result = new StringBuilder(); + for (char c : s.toCharArray()) { + if (c > 127 || c == '&') { + final int i = c; + result.append("&#" + i + ";"); + } else { + result.append(c); + } + } + return result.toString(); + } + + private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(IEntity entity, + final String circleAbsolutePath, int cellSpacing, boolean classes) { + final StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append(""); + if (circleAbsolutePath == null) { + sb.append(""); + sb.append("
"); + } else { + sb.append(""); + sb.append(""); + } + + appendLabelAndStereotype(entity, sb, classes); + sb.append("
"); + return sb.toString(); + } + + private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(IEntity entity, final String circleAbsolutePath, + int spring, boolean classes, int border) throws IOException { + if (spring == 0) { + return getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(entity, circleAbsolutePath, 0, classes); + } + final StringBuilder sb = new StringBuilder(); + + sb + .append(""); + sb.append(""); + + for (int i = 0; i < spring; i++) { + sb.append(""); + } + + if (circleAbsolutePath != null) { + if (circleAbsolutePath.endsWith(".png")) { + final BufferedImage im = ImageIO.read(new File(circleAbsolutePath)); + final int height = im.getHeight(); + final int width = im.getWidth(); + sb.append(""); + } else if (circleAbsolutePath.endsWith(".eps")) { + sb.append(""); + } + } + + sb.append(""); + + for (int i = 0; i < spring; i++) { + sb.append(""); + } + sb.append("
"); + appendLabelAndStereotype(entity, sb, classes); + sb.append("
"); + return sb.toString(); + } + + private void appendLabelAndStereotype(IEntity entity, final StringBuilder sb, boolean classes) { + final Stereotype stereotype = getStereotype(entity); + if (isThereLabel(stereotype)) { + sb.append("
"); + sb.append(manageHtmlIB(stereotype.getLabel(), classes ? FontParam.CLASS_STEREOTYPE + : FontParam.OBJECT_STEREOTYPE)); + sb.append("
"); + } + String display = entity.getDisplay(); + final boolean italic = entity.getType() == EntityType.ABSTRACT_CLASS + || entity.getType() == EntityType.INTERFACE; + if (italic) { + display = "" + display; + } + sb.append(manageHtmlIB(display, classes ? FontParam.CLASS : FontParam.OBJECT)); + } + + private String getHtmlHeaderTableForClassOrInterfaceOrEnumNew(Entity entity, final String circleAbsolutePath) { + final StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append("
"); + + appendLabelAndStereotype(entity, sb, true); + sb.append("
"); + return sb.toString(); + } + + private boolean isThereLabel(final Stereotype stereotype) { + return stereotype != null && stereotype.getLabel() != null; + } + + private Stereotype getStereotype(IEntity entity) { + if (data.showPortion(EntityPortion.STEREOTYPE, entity) == false) { + return null; + } + return entity.getStereotype(); + } + + public final boolean isUnderline() { + return underline; + } + + private boolean workAroundDotBug() { + for (Link link : data.getLinks()) { + if (link.getLength() != 1) { + return false; + } + } + if (data.getUmlDiagramType() == UmlDiagramType.CLASS && allEntitiesAreClasses(data.getEntities().values())) { + return true; + } + for (IEntity ent : data.getEntities().values()) { + if (data.getAllLinkedTo(ent).size() == 0) { + return true; + } + } + return false; + } + + private boolean allEntitiesAreClasses(Collection entities) { + for (IEntity ent : entities) { + if (ent.getType() != EntityType.CLASS && ent.getType() != EntityType.ABSTRACT_CLASS + && ent.getType() != EntityType.INTERFACE && ent.getType() != EntityType.ENUM) { + return false; + } + } + return true; + } + + private boolean isSpecialGroup(Group g) { + if (g.getType() == GroupType.STATE) { + return true; + } + if (g.getType() == GroupType.CONCURRENT_STATE) { + throw new IllegalStateException(); + } + if (data.isThereLink(g)) { + return true; + } + return false; + } + + public static final String getLastDotSignature() { + return lastDotSignature; + } + + public static final void reset() { + lastDotSignature = null; + } + + public void clean() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java new file mode 100644 index 000000000..89aca01aa --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java @@ -0,0 +1,163 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3977 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.Log; + +public class DrawFile { + + private final LazyCached png2; + private final LazyCached svg2; + private final LazyCached eps2; + + private int widthPng = -1; + private int heightPng = -1; + + public DrawFile(Lazy png) { + this(png, (Lazy) null, null); + } + + public DrawFile(Lazy png, Lazy svg) { + this(png, svg, null); + } + + public DrawFile(Lazy png, Lazy svg, Lazy eps) { + this.png2 = new LazyCached(png); + this.svg2 = new LazyCached(svg); + this.eps2 = new LazyCached(eps); + } + + public DrawFile(File fPng, String svg, File fEps) { + this(new Unlazy(fPng), new Unlazy(svg), new Unlazy(fEps)); + } + + public DrawFile(File fPng, String svg, Lazy eps) { + this(new Unlazy(fPng), new Unlazy(svg), eps); + } + + public DrawFile(Lazy png, String svg, Lazy eps) { + this(png, new Unlazy(svg), eps); + } + + public DrawFile(File f, String svg) { + this(f, svg, (File) null); + } + + public File getPngOrEps(boolean isEps) throws IOException { + if (isEps) { + if (eps2 == null) { + throw new UnsupportedOperationException("No eps for " + getPng().getAbsolutePath()); + } + return getEps(); + } else { + return getPng(); + } + } + + public File getPng() throws IOException { + return png2.getNow(); + } + + public String getSvg() throws IOException { + return svg2.getNow(); + } + + public File getEps() throws IOException { + return eps2.getNow(); + } + + private void initSize() throws IOException { + final BufferedImage im = ImageIO.read(getPng()); + widthPng = im.getWidth(); + heightPng = im.getHeight(); + } + + public void delete() { + Thread.yield(); + if (png2 != null && png2.isLoaded()) { + try { + Log.info("Deleting temporary file " + getPng()); + final boolean ok = getPng().delete(); + if (ok == false) { + Log.error("Cannot delete: " + getPng()); + } + } catch (IOException e) { + e.printStackTrace(); + Log.error("Problem deleting PNG file"); + } + } + if (eps2 != null && eps2.isLoaded()) { + try { + Log.info("Deleting temporary file " + getEps()); + final boolean ok2 = getEps().delete(); + if (ok2 == false) { + Log.error("Cannot delete: " + getEps()); + } + } catch (IOException e) { + e.printStackTrace(); + Log.error("Problem deleting EPS file"); + } + + } + } + + public final int getWidthPng() throws IOException { + if (widthPng == -1) { + initSize(); + } + return widthPng; + } + + public final int getHeightPng() throws IOException { + if (widthPng == -1) { + initSize(); + } + return heightPng; + } + + // @Override + // public String toString() { + // if (svg == null) { + // return getPng().toString(); + // } + // return png + " " + svg.length(); + // } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/Graphviz.java b/src/net/sourceforge/plantuml/cucadiagram/dot/Graphviz.java new file mode 100644 index 000000000..098bc2ae7 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/Graphviz.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +public interface Graphviz { + + void createPng(OutputStream os) throws IOException, InterruptedException; + + File getDotExe(); + + String dotVersion() throws IOException, InterruptedException; +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java new file mode 100644 index 000000000..b7f1c952a --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizLinux.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; + +class GraphvizLinux extends AbstractGraphviz { + + GraphvizLinux(String dotString, String... type) { + super(dotString, type); + } + + @Override + protected File specificDotExe() { + final File usrLocalBinDot = new File("/usr/local/bin/dot"); + + if (usrLocalBinDot.exists()) { + return usrLocalBinDot; + } + final File usrBinDot = new File("/usr/bin/dot"); + return usrBinDot; + } + + @Override + String getCommandLine() { + final StringBuilder sb = new StringBuilder(); + sb.append(getDotExe().getAbsolutePath()); + appendImageType(sb); + return sb.toString(); + } + + @Override + String getCommandLineVersion() { + final StringBuilder sb = new StringBuilder(); + sb.append(getDotExe().getAbsolutePath()); + sb.append(" -V"); + return sb.toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizMaker.java new file mode 100644 index 000000000..3dd67fbbf --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizMaker.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5380 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.IOException; + +public interface GraphvizMaker { + + String createDotString() throws IOException; + + boolean isUnderline(); + + void clean(); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java new file mode 100644 index 000000000..0cccf627e --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizUtils.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; +import java.io.IOException; + +public class GraphvizUtils { + + private static boolean isWindows() { + return File.separatorChar == '\\'; + } + + public static Graphviz create(String dotString, String... type) { + if (isWindows()) { + return new GraphvizWindows(dotString, type); + } + return new GraphvizLinux(dotString, type); + } + + static public File getDotExe() { + return create(null, "png").getDotExe(); + } + + public static String getenvGraphvizDot() { + final String env = System.getProperty("GRAPHVIZ_DOT"); + if (env != null) { + return env; + } + return System.getenv("GRAPHVIZ_DOT"); + } + + private static String dotVersion = null; + + public static String dotVersion() throws IOException, InterruptedException { + if (dotVersion == null) { + if (GraphvizUtils.getDotExe() == null) { + dotVersion = "Error: Dot not installed"; + } else if (GraphvizUtils.getDotExe().exists() == false) { + dotVersion = "Error: " + GraphvizUtils.getDotExe().getAbsolutePath() + " does not exist"; + } else if (GraphvizUtils.getDotExe().isFile() == false) { + dotVersion = "Error: " + GraphvizUtils.getDotExe().getAbsolutePath() + " is not a file"; + } else if (GraphvizUtils.getDotExe().canRead() == false) { + dotVersion = "Error: " + GraphvizUtils.getDotExe().getAbsolutePath() + " cannot be read"; + } else { + dotVersion = create(null, "png").dotVersion(); + } + } + return dotVersion; + } +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java new file mode 100644 index 000000000..dc4d31670 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java @@ -0,0 +1,111 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +class GraphvizWindows extends AbstractGraphviz { + + @Override + protected File specificDotExe() { + final File result = searchInDir(new File("c:/Program Files")); + if (result != null) { + return result; + } + final File result86 = searchInDir(new File("c:/Program Files (x86)")); + if (result86 != null) { + return result86; + } + return null; + } + + private static File searchInDir(final File programFile) { + if (programFile.exists() == false || programFile.isDirectory() == false) { + return null; + } + final List dots = new ArrayList(); + for (File f : programFile.listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.isDirectory() && pathname.getName().startsWith("Graphviz"); + } + })) { + final File result = new File(new File(f, "bin"), "dot.exe"); + if (result.exists() && result.canRead()) { + dots.add(result.getAbsoluteFile()); + } + } + return higherVersion(dots); + } + + static File higherVersion(List dots) { + if (dots.size() == 0) { + return null; + } + Collections.sort(dots, Collections.reverseOrder()); + return dots.get(0); + } + + GraphvizWindows(String dotString, String... type) { + super(dotString, type); + } + + @Override + String getCommandLine() { + final StringBuilder sb = new StringBuilder(); + appendDoubleQuoteOnWindows(sb); + sb.append(getDotExe().getAbsolutePath()); + appendDoubleQuoteOnWindows(sb); + appendImageType(sb); + return sb.toString(); + } + + private static void appendDoubleQuoteOnWindows(final StringBuilder sb) { + sb.append('\"'); + } + + @Override + String getCommandLineVersion() { + final StringBuilder sb = new StringBuilder(); + appendDoubleQuoteOnWindows(sb); + sb.append(getDotExe().getAbsolutePath()); + appendDoubleQuoteOnWindows(sb); + sb.append(" -V"); + return sb.toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java new file mode 100644 index 000000000..19dbd3f18 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java @@ -0,0 +1,192 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5385 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupHierarchy; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.skin.rose.Rose; + +public final class GroupPngMaker { + + private final CucaDiagram diagram; + private final Group group; + private final Rose rose = new Rose(); + private final FileFormat fileFormat; + + class InnerGroupHierarchy implements GroupHierarchy { + + public Collection getChildrenGroups(Group parent) { + if (parent == null) { + return diagram.getChildrenGroups(group); + } + return diagram.getChildrenGroups(parent); + } + + public boolean isEmpty(Group g) { + return diagram.isEmpty(g); + } + + } + + public GroupPngMaker(CucaDiagram diagram, Group group, FileFormat fileFormat) throws IOException { + this.diagram = diagram; + this.group = group; + this.fileFormat = fileFormat; + } + + public void createPng(OutputStream os, List dotStrings) throws IOException, InterruptedException { + final Map imageFiles = new HashMap(); + // final Map imagesLink = new HashMap(); + try { + // populateImages(imageFiles); + // populateImagesLink(imagesLink); + final GraphvizMaker dotMaker = createDotMaker(dotStrings); + final String dotString = dotMaker.createDotString(); + + // if (OptionFlags.getInstance().isKeepTmpFiles()) { + // traceDotString(dotString); + // } + + // final boolean isUnderline = dotMaker.isUnderline(); + final Graphviz graphviz = GraphvizUtils.create(dotString, "png"); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + + final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + final BufferedImage im = ImageIO.read(bais); + bais.close(); + // if (isUnderline) { + // new UnderlineTrick(im, new Color(Integer.parseInt("FEFECF", 16)), + // Color.BLACK).process(); + // } + + PngIO.write(im, os, diagram.getMetadata()); + } finally { + cleanTemporaryFiles(imageFiles); + } + } + + public String createSvg(List dotStrings) throws IOException, InterruptedException { + final Map imageFiles = new HashMap(); + // final Map imagesLink = new HashMap(); + try { + // populateImages(imageFiles); + // populateImagesLink(imagesLink); + final GraphvizMaker dotMaker = createDotMaker(dotStrings); + final String dotString = dotMaker.createDotString(); + + // if (OptionFlags.getInstance().isKeepTmpFiles()) { + // traceDotString(dotString); + // } + + // final boolean isUnderline = dotMaker.isUnderline(); + final Graphviz graphviz = GraphvizUtils.create(dotString, "svg"); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + + String svg = new String(baos.toByteArray(), "UTF-8"); + svg = removeSvgXmlHeader(svg); + return svg; + + } finally { + cleanTemporaryFiles(imageFiles); + } + } + + private static String removeSvgXmlHeader(String svg) { + svg = svg.replaceFirst("(?i)<\\?xml[\\s\\S]*?]*>", ""); + svg = svg.replaceFirst("(?i)", ""); + + return svg; + } + + private void cleanTemporaryFiles(final Map imageFiles) { + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + for (File f : imageFiles.values()) { + StaticFiles.delete(f); + } + } + } + + GraphvizMaker createDotMaker(List dotStrings) { + final List links = getPureInnerLinks(); + final DotData dotData = new DotData(group, links, group.entities(), diagram.getUmlDiagramType(), diagram + .getSkinParam(), group.getRankdir(), new InnerGroupHierarchy()); + // dotData.putAllImages(images); + // dotData.putAllStaticImages(staticImages); + // dotData.putAllImagesLink(imagesLink); + + return new DotMaker(dotData, dotStrings, fileFormat); + } + + private List getPureInnerLinks() { + final List result = new ArrayList(); + for (Link link : diagram.getLinks()) { + final IEntity e1 = link.getEntity1(); + final IEntity e2 = link.getEntity2(); + if (e1.getParent() == group && e1.getType() != EntityType.GROUP && e2.getParent() == group + && e2.getType() != EntityType.GROUP) { + result.add(link); + } + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/Lazy.java b/src/net/sourceforge/plantuml/cucadiagram/dot/Lazy.java new file mode 100644 index 000000000..400ddba0a --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/Lazy.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3977 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.IOException; + +public interface Lazy { + public O getNow() throws IOException; +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java b/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java new file mode 100644 index 000000000..3cc5a6d51 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3977 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.IOException; + +public class LazyCached implements Lazy { + + private O data; + private final Lazy lazy; + + public LazyCached(Lazy lazy) { + this.lazy = lazy; + } + + public O getNow() throws IOException { + if (data == null) { + this.data = this.lazy.getNow(); + } + return this.data; + } + + public boolean isLoaded() { + return data != null; + } +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java b/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java new file mode 100644 index 000000000..10e76396a --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java @@ -0,0 +1,314 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4302 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.posimo.Block; +import net.sourceforge.plantuml.posimo.Cluster; +import net.sourceforge.plantuml.posimo.EntityImageBlock; +import net.sourceforge.plantuml.posimo.EntityImageClass2; +import net.sourceforge.plantuml.posimo.Frame; +import net.sourceforge.plantuml.posimo.GraphvizSolverB; +import net.sourceforge.plantuml.posimo.IEntityImageBlock; +import net.sourceforge.plantuml.posimo.Label; +import net.sourceforge.plantuml.posimo.LabelImage; +import net.sourceforge.plantuml.posimo.MargedBlock; +import net.sourceforge.plantuml.posimo.Path; +import net.sourceforge.plantuml.posimo.PathDrawerInterface; +import net.sourceforge.plantuml.posimo.PositionableUtils; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public final class PlayField { + + private final Rose rose = new Rose(); + private final ISkinParam skinParam; + + private final Cluster root = new Cluster(null); + private final Map paths = new LinkedHashMap(); + + private final Map blocks = new HashMap(); + private final Map clusters = new HashMap(); + + final private double marginLabel = 6; + + public PlayField(ISkinParam skinParam) { + this.skinParam = skinParam; + } + + public void initInternal(Collection entities, + Collection links, StringBounder stringBounder) { + if (blocks.size() != 0 || paths.size() != 0 /* || images.size() != 0 */ + || clusters.size() != 0) { + throw new IllegalStateException(); + } + if (entities.size() != new HashSet(entities).size()) { + throw new IllegalArgumentException("Duplicate entities"); + } + if (links.size() != new HashSet(links).size()) { + throw new IllegalArgumentException("Duplicate entities"); + } + + for (IEntity ent : entities) { + if (ent.getType() == EntityType.GROUP + && ent.getParent().isAutonom() == false) { + clusters.put(ent, new Cluster(root)); + System.err.println("Creating cluster for " + ent + " " + + clusters.get(ent)); + } + } + + for (IEntity ent : entities) { + System.err.println("ENT=" + ent); + if (ent.getType() == EntityType.GROUP + && ent.getParent().isAutonom() == false) { + assert clusters.containsKey(ent); + continue; + } + assert clusters.containsKey(ent) == false; + Cluster parentCluster = root; + if (ent.getType() != EntityType.GROUP && ent.getParent() != null) { + parentCluster = clusters + .get(ent.getParent().getEntityCluster()); + if (parentCluster == null) { + parentCluster = root; + } + } + final IEntityImageBlock entityImageBlock = createEntityImageBlock( + links, ent); + // final Dimension2D d = + // entityImageBlock.getDimension(stringBounder); + // final Block b = new Block(uid++, d.getWidth() + 2 * + // marginDecorator, d.getHeight() + 2 * marginDecorator); + final MargedBlock b = new MargedBlock(stringBounder, + entityImageBlock, getMargin(ent, links)); + + blocks.put(ent, b); + // images.put(ent, entityImageBlock); + parentCluster.addBloc(b.getBlock()); + } + + for (Cluster cl : clusters.values()) { + if (cl.getContents().size() == 0) { + throw new IllegalStateException(); + } + } + + for (Link link : links) { + System.err.println("LINK=" + link); + if (entities.contains(link.getEntity1()) + && entities.contains(link.getEntity2())) { + final Block b1 = getToto(link.getEntity1()); + final Block b2 = getToto(link.getEntity2()); + final Label label; + if (link.getLabel() == null) { + label = null; + } else { + final LabelImage labelImage = new LabelImage(link, rose, + skinParam); + final Dimension2D dim = Dimension2DDouble.delta(labelImage + .getDimension(stringBounder), marginLabel); + label = new Label(dim.getWidth(), dim.getHeight()); + } + final Path p = new Path(b1, b2, label); + paths.put(p, link); + } + } + } + + private int getMargin(IEntity ent, Collection links) { + int result = 0; + for (Link link : links) { + if (link.getEntity2()==ent) { + final LinkDecor decor = link.getType().getDecor1(); + result = Math.max(result, decor.getSize()); + } + if (link.getEntity1()==ent) { + final LinkDecor decor = link.getType().getDecor2(); + result = Math.max(result, decor.getSize()); + } + + } + return result; + //return 40; + } + + private Block getToto(IEntity ent) { + final MargedBlock result = blocks.get(ent); + if (result != null) { + return result.getBlock(); + } + if (clusters.containsKey(ent) == false) { + throw new IllegalArgumentException(); + } + return blocks.get(getOneOf(ent.getParent())).getBlock(); + } + + private IEntity getOneOf(Group gr) { + assert gr != null; + return gr.entities().values().iterator().next(); + } + + public void drawInternal(UGraphic ug) { + + for (Map.Entry ent : clusters.entrySet()) { + final Frame frame = new Frame(StringUtils.getWithNewlines(ent + .getKey().getDisplay()), Color.BLACK, skinParam + .getFont(FontParam.CLASS), rose.getHtmlColor(skinParam, + ColorParam.classBorder).getColor()); + final Rectangle2D rect = PositionableUtils.convert(ent.getValue()); + final double oldX = ug.getTranslateX(); + final double oldY = ug.getTranslateY(); + ug.translate(rect.getX(), rect.getY()); + frame.drawU(ug, new Dimension2DDouble(rect.getWidth(), rect + .getHeight()), null); + ug.setTranslate(oldX, oldY); + } + + for (Map.Entry ent : paths.entrySet()) { + final LinkType type = ent.getValue().getType(); + final PathDrawerInterface pathDrawer = PathDrawerInterface.create( + new Rose(), skinParam, type); + final Path p = ent.getKey(); + ug.getParam().setColor( + rose.getHtmlColor(skinParam, ColorParam.classBorder) + .getColor()); + // pathDrawer.drawPathBefore(ug, PositionableUtils.addMargin(p + // .getStart(), -marginDecorator, -marginDecorator), + // PositionableUtils.addMargin(p.getEnd(), -marginDecorator, + // -marginDecorator), p); + if (p.getLabel() != null) { + ug.getParam().setColor(Color.BLACK); + drawLabel(ug, p); + } + } + + for (Map.Entry ent : blocks.entrySet()) { + final MargedBlock b = ent.getValue(); + final Point2D pos = b.getImagePosition().getPosition(); + b.getImageBlock().drawU(ug, pos.getX(), pos.getY(), 0, 0); + } + + for (Map.Entry ent : paths.entrySet()) { + final LinkType type = ent.getValue().getType(); + final PathDrawerInterface pathDrawer = PathDrawerInterface.create( + new Rose(), skinParam, type); + final Path p = ent.getKey(); + ug.getParam().setColor( + rose.getHtmlColor(skinParam, ColorParam.classBorder) + .getColor()); + // pathDrawer.drawPathAfter(ug, PositionableUtils.addMargin(p + // .getStart(), -marginDecorator, -marginDecorator), + // PositionableUtils.addMargin(p.getEnd(), -marginDecorator, + // -marginDecorator), p); + pathDrawer.drawPathAfter(ug, getMargedBlock(p.getStart()) + .getImagePosition(), getMargedBlock(p.getEnd()) + .getImagePosition(), p); + } + } + + private MargedBlock getMargedBlock(Block b) { + for (MargedBlock margedBlock : blocks.values()) { + if (margedBlock.getBlock() == b) { + return margedBlock; + } + } + throw new IllegalArgumentException(); + } + + public Dimension2D solve() throws IOException, InterruptedException { + final GraphvizSolverB solver = new GraphvizSolverB(); + System.err.println("sub=" + root.getSubClusters()); + final Dimension2D dim = Dimension2DDouble.delta(solver.solve(root, + paths.keySet()), 20); + return dim; + } + + private void drawLabel(UGraphic ug, Path p) { + final Label label = p.getLabel(); + final Point2D pos = label.getPosition(); + if (OptionFlags.getInstance().isDebugDot()) { + ug.getParam().setColor(Color.GREEN); + ug.getParam().setBackcolor(null); + final Dimension2D dim = label.getSize(); + ug.draw(pos.getX(), pos.getY(), new URectangle(dim.getWidth(), dim + .getHeight())); + final LabelImage labelImage = new LabelImage(paths.get(p), rose, + skinParam); + final Dimension2D dimImage = labelImage.getDimension(ug + .getStringBounder()); + ug.draw(pos.getX(), pos.getY(), new URectangle(dimImage.getWidth(), + dimImage.getHeight())); + } + final LabelImage labelImage = new LabelImage(paths.get(p), rose, + skinParam); + labelImage.drawU(ug, pos.getX(), pos.getY()); + } + + private IEntityImageBlock createEntityImageBlock(Collection links, + IEntity ent) { + if (ent.getType() == EntityType.CLASS + || ent.getType() == EntityType.ABSTRACT_CLASS + || ent.getType() == EntityType.INTERFACE + || ent.getType() == EntityType.ENUM) { + return new EntityImageClass2(ent, rose, skinParam, links); + } + return new EntityImageBlock(ent, rose, skinParam, links); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java b/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java new file mode 100644 index 000000000..8bc69aaa8 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/ProcessRunner.java @@ -0,0 +1,111 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import net.sourceforge.plantuml.Log; + +public class ProcessRunner { + + private final String cmd; + + private String error; + private String out; + + public ProcessRunner(String cmd) { + this.cmd = cmd; + } + + public void run(byte in[], OutputStream redirection) throws IOException, InterruptedException { + final Process process = Runtime.getRuntime().exec(cmd); + final ThreadStream errorStream = new ThreadStream(process.getErrorStream(), null); + final ThreadStream outStream = new ThreadStream(process.getInputStream(), redirection); + errorStream.start(); + outStream.start(); + if (in != null) { + final OutputStream os = process.getOutputStream(); + os.write(in); + os.close(); + } + process.waitFor(); + errorStream.join(10000L); + outStream.join(10000L); + this.out = outStream.sb.toString(); + this.error = errorStream.sb.toString(); + } + + static class ThreadStream extends Thread { + + private final InputStream streamToRead; + private final OutputStream redirection; + private final StringBuilder sb = new StringBuilder(); + + ThreadStream(InputStream streamToRead, OutputStream redirection) { + this.streamToRead = streamToRead; + this.redirection = redirection; + } + + @Override + public void run() { + Log.debug("STARTING " + this); + int read = 0; + try { + while ((read = streamToRead.read()) != -1) { + if (redirection == null) { + sb.append((char) read); + } else { + redirection.write(read); + } + } + } catch (IOException e) { + e.printStackTrace(); + sb.append('\n'); + sb.append(e.toString()); + } + Log.debug("FINISHING " + this); + } + } + + public final String getError() { + return error; + } + + public final String getOut() { + return out; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java b/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java new file mode 100644 index 000000000..ef7172211 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java @@ -0,0 +1,408 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5339 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Map; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.graphic.CircledCharacter; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.skin.CircleInterface; +import net.sourceforge.plantuml.skin.StickMan; +import net.sourceforge.plantuml.skin.UDrawable; +import net.sourceforge.plantuml.skin.VisibilityModifier; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; + +public class StaticFiles { + + private final String circleInterfaceName = "cinterface.png"; + private final String lollipopName = "lollipop.png"; + private final String actorName = "actor.png"; + private final String cName = "stereotypec.png"; + private final String iName = "stereotypei.png"; + private final String aName = "stereotypea.png"; + private final String eName = "stereotypee.png"; + + private final Color stereotypeCBackground; + private final Color stereotypeIBackground; + private final Color stereotypeABackground; + private final Color stereotypeEBackground; + + private final Color interfaceBorder; + private final Color classborder; + private final Color actorBorder; + private final Color classBackground; + private final Color actorBackground; + private final Color interfaceBackground; + private final Color background; + + final private Font circledFont; + final private double radius; + + private final Map staticImages = new EnumMap(EntityType.class); + private final Map visibilityImages = new EnumMap( + VisibilityModifier.class); + + private final Map foregroundColor = new EnumMap( + VisibilityModifier.class); + private final Map backgroundColor = new EnumMap( + VisibilityModifier.class); + + private static final Collection toDelete = new ArrayList(); + + private void deleteOnExit() { + if (toDelete.isEmpty()) { + toDelete.addAll(staticImages.values()); + toDelete.addAll(visibilityImages.values()); + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + for (DrawFile f : toDelete) { + f.delete(); + } + } + } + }); + } + } + + public StaticFiles(ISkinParam param) throws IOException { + final Rose rose = new Rose(); + radius = param.getCircledCharacterRadius(); + circledFont = param.getFont(FontParam.CIRCLED_CHARACTER); + // circledFont = new Font("Courier", Font.BOLD, 17); + + actorBorder = rose.getHtmlColor(param, ColorParam.actorBorder).getColor(); + classborder = rose.getHtmlColor(param, ColorParam.classBorder).getColor(); + interfaceBorder = rose.getHtmlColor(param, ColorParam.interfaceBorder).getColor(); + interfaceBackground = rose.getHtmlColor(param, ColorParam.interfaceBackground).getColor(); + actorBackground = rose.getHtmlColor(param, ColorParam.actorBackground).getColor(); + classBackground = rose.getHtmlColor(param, ColorParam.classBackground).getColor(); + stereotypeCBackground = rose.getHtmlColor(param, ColorParam.stereotypeCBackground).getColor(); + stereotypeABackground = rose.getHtmlColor(param, ColorParam.stereotypeABackground).getColor(); + stereotypeIBackground = rose.getHtmlColor(param, ColorParam.stereotypeIBackground).getColor(); + stereotypeEBackground = rose.getHtmlColor(param, ColorParam.stereotypeEBackground).getColor(); + + background = param.getBackgroundColor().getColor(); + + final File dir = getTmpDir(); + staticImages.put(EntityType.LOLLIPOP, ensurePngLollipopPresent(dir)); + staticImages.put(EntityType.CIRCLE_INTERFACE, ensurePngCircleInterfacePresent(dir)); + staticImages.put(EntityType.ACTOR, ensurePngActorPresent(dir)); + staticImages.put(EntityType.ABSTRACT_CLASS, ensurePngAPresent(dir)); + staticImages.put(EntityType.CLASS, ensurePngCPresent(dir)); + staticImages.put(EntityType.INTERFACE, ensurePngIPresent(dir)); + staticImages.put(EntityType.ENUM, ensurePngEPresent(dir)); + + if (param.classAttributeIconSize() > 0) { + for (VisibilityModifier modifier : EnumSet.allOf(VisibilityModifier.class)) { + + final Color back = modifier.getBackground() == null ? null : rose.getHtmlColor(param, + modifier.getBackground()).getColor(); + final Color fore = rose.getHtmlColor(param, modifier.getForeground()).getColor(); + + backgroundColor.put(modifier, back); + foregroundColor.put(modifier, fore); + visibilityImages.put(modifier, + ensureVisibilityModifierPresent(modifier, dir, param.classAttributeIconSize())); + } + } + + deleteOnExit(); + } + + public File getTmpDir() { + final File tmpDir = new File(System.getProperty("java.io.tmpdir")); + if (tmpDir.exists() == false || tmpDir.isDirectory() == false) { + throw new IllegalStateException(); + } + return tmpDir; + } + + public static void delete(File f) { + if (f == null) { + return; + } + Thread.yield(); + Log.info("Deleting temporary file " + f); + final boolean ok = f.delete(); + if (ok == false) { + Log.error("Cannot delete: " + f); + } + } + + private DrawFile ensurePngActorPresent(final File dir) throws IOException { + final StickMan stickMan = new StickMan(actorBackground, actorBorder); + + final Lazy lpng = new Lazy() { + public File getNow() throws IOException { + final EmptyImageBuilder builder = new EmptyImageBuilder((int) stickMan.getPreferredWidth(null), + (int) stickMan.getPreferredHeight(null), background); + + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + stickMan.drawU(new UGraphicG2d(g2d, null)); + + final File png = new File(dir, actorName); + Log.info("Creating temporary file: " + png); + ImageIO.write(im, "png", png); + return png; + } + }; + + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + final File epsFile = new File(dir, actorName.replaceFirst("\\.png", ".eps")); + UGraphicEps.copyEpsToFile(stickMan, epsFile); + return epsFile; + } + }; + + return new DrawFile(lpng, UGraphicG2d.getSvgString(stickMan), leps); + } + + private DrawFile ensurePngCircleInterfacePresent(final File dir) throws IOException { + + final CircleInterface circleInterface = new CircleInterface(interfaceBackground, interfaceBorder); + + final Lazy lpng = new Lazy() { + + public File getNow() throws IOException { + final EmptyImageBuilder builder = new EmptyImageBuilder((int) circleInterface.getPreferredWidth(null), + (int) circleInterface.getPreferredHeight(null), background); + + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + circleInterface.drawU(new UGraphicG2d(g2d, null)); + + final File png = new File(dir, circleInterfaceName); + Log.info("Creating temporary file: " + png); + ImageIO.write(im, "png", png); + return png; + } + }; + + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + final File epsFile = new File(dir, circleInterfaceName.replaceFirst("\\.png", ".eps")); + Log.info("Creating temporary file: " + epsFile); + UGraphicEps.copyEpsToFile(circleInterface, epsFile); + return epsFile; + } + }; + + return new DrawFile(lpng, UGraphicG2d.getSvgString(circleInterface), leps); + + } + + private DrawFile ensurePngLollipopPresent(final File dir) throws IOException { + + final CircleInterface circleInterface = new CircleInterface(interfaceBackground, interfaceBorder, 10, 2); + + final Lazy lpng = new Lazy() { + + public File getNow() throws IOException { + final EmptyImageBuilder builder = new EmptyImageBuilder((int) circleInterface.getPreferredWidth(null), + (int) circleInterface.getPreferredHeight(null), background); + + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + circleInterface.drawU(new UGraphicG2d(g2d, null)); + + final File result = new File(dir, lollipopName); + Log.info("Creating temporary file: " + result); + ImageIO.write(im, "png", result); + return result; + } + }; + + final Lazy leps = new Lazy() { + + public File getNow() throws IOException { + final File epsFile = new File(dir, lollipopName.replaceFirst("\\.png", ".eps")); + Log.info("Creating temporary file: " + epsFile); + UGraphicEps.copyEpsToFile(circleInterface, epsFile); + return epsFile; + } + }; + + return new DrawFile(lpng, UGraphicG2d.getSvgString(circleInterface), leps); + + } + + private DrawFile ensurePngCPresent(File dir) throws IOException { + final CircledCharacter circledCharacter = new CircledCharacter('C', radius, circledFont, stereotypeCBackground, + classborder, Color.BLACK); + return generateCircleCharacterFile(dir, cName, circledCharacter, classBackground); + } + + private DrawFile ensurePngAPresent(File dir) throws IOException { + final CircledCharacter circledCharacter = new CircledCharacter('A', radius, circledFont, stereotypeABackground, + classborder, Color.BLACK); + return generateCircleCharacterFile(dir, aName, circledCharacter, classBackground); + } + + private DrawFile ensurePngIPresent(File dir) throws IOException { + final CircledCharacter circledCharacter = new CircledCharacter('I', radius, circledFont, stereotypeIBackground, + classborder, Color.BLACK); + return generateCircleCharacterFile(dir, iName, circledCharacter, classBackground); + } + + private DrawFile ensurePngEPresent(File dir) throws IOException { + final CircledCharacter circledCharacter = new CircledCharacter('E', radius, circledFont, stereotypeEBackground, + classborder, Color.BLACK); + return generateCircleCharacterFile(dir, eName, circledCharacter, classBackground); + } + + private DrawFile generateCircleCharacterFile(File dir, String filename, final CircledCharacter circledCharacter, + final Color yellow) throws IOException { + final File png = new File(dir, filename); + final File epsFile = new File(dir, filename.replaceFirst("\\.png", ".eps")); + + return generateCircleCharacter(png, epsFile, circledCharacter, yellow); + } + + public DrawFile generateCircleCharacter(final File png, final File epsFile, + final CircledCharacter circledCharacter, final Color yellow) throws IOException { + + final Lazy lpng = new Lazy() { + + public File getNow() throws IOException { + Log.info("Creating temporary file: " + png); + final EmptyImageBuilder builder = new EmptyImageBuilder(90, 90, yellow); + BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + final StringBounder stringBounder = StringBounderUtils.asStringBounder(g2d); + + circledCharacter.draw(g2d, 0, 0); + im = im.getSubimage(0, 0, (int) circledCharacter.getPreferredWidth(stringBounder) + 5, + (int) circledCharacter.getPreferredHeight(stringBounder) + 1); + + ImageIO.write(im, "png", png); + return png; + } + }; + + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + Log.info("Creating temporary file: " + epsFile); + UGraphicEps.copyEpsToFile(circledCharacter, epsFile); + return epsFile; + } + }; + + return new DrawFile(lpng, UGraphicG2d.getSvgString(circledCharacter), leps); + } + + public final Map getStaticImages() { + return Collections.unmodifiableMap(staticImages); + } + + public final Map getVisibilityImages() { + return Collections.unmodifiableMap(visibilityImages); + } + + public DrawFile getDrawFile(String pngPath) throws IOException { + final File searched = new File(pngPath).getCanonicalFile(); + for (DrawFile drawFile : staticImages.values()) { + final File png = drawFile.getPng().getCanonicalFile(); + if (png.equals(searched)) { + return drawFile; + } + } + for (DrawFile drawFile : visibilityImages.values()) { + final File png = drawFile.getPng().getCanonicalFile(); + if (png.equals(searched)) { + return drawFile; + } + } + return null; + } + + private DrawFile ensureVisibilityModifierPresent(final VisibilityModifier modifier, final File dir, final int size) + throws IOException { + final UDrawable drawable = modifier.getUDrawable(size, foregroundColor.get(modifier), + backgroundColor.get(modifier)); + + final Lazy lpng = new Lazy() { + public File getNow() throws IOException { + final File png = new File(dir, modifier.name() + ".png"); + Log.info("Creating temporary file: " + png); + final EmptyImageBuilder builder = new EmptyImageBuilder(size, size, classBackground); + final BufferedImage im = builder.getBufferedImage(); + drawable.drawU(new UGraphicG2d(builder.getGraphics2D(), im)); + ImageIO.write(im, "png", png); + return png; + } + }; + + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + final File eps = new File(dir, modifier.name() + ".eps"); + Log.info("Creating temporary file: " + eps); + UGraphicEps.copyEpsToFile(drawable, eps); + return eps; + } + }; + + return new DrawFile(lpng, UGraphicG2d.getSvgString(drawable), leps); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/UnderlineTrick.java b/src/net/sourceforge/plantuml/cucadiagram/dot/UnderlineTrick.java new file mode 100644 index 000000000..06fd868b6 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/UnderlineTrick.java @@ -0,0 +1,134 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +public class UnderlineTrick { + + static class Segment { + final private int start; + final private int end; + + Segment(int start, int end) { + this.start = start; + this.end = end; + } + + @Override + public String toString() { + return "" + start + "-" + end; + } + } + + public static void main(String[] args) throws IOException { + if (args.length == 0) { + System.err.println("Usage: fileName searchedColor underlineColor"); + System.exit(0); + } + final File f = new File(args[0]); + final BufferedImage im = ImageIO.read(f); + final Color searchedColor = new Color(Integer.parseInt(args[1], 16)); + final Color underlineColor = new Color(Integer.parseInt(args[2], 16)); + new UnderlineTrick(im, searchedColor, underlineColor).process(); + ImageIO.write(im, "png", f); + + } + + private final BufferedImage im; + private final int searchedColor; + private final int underlineColor; + + public UnderlineTrick(BufferedImage im, Color searchedColor, Color underlineColor) { + this.im = im; + this.searchedColor = searchedColor.getRGB(); + this.underlineColor = underlineColor.getRGB(); + } + + public void process() { + for (int line = 0; line < im.getHeight(); line++) { + int x = 0; + while (x < im.getWidth()) { + final Segment segStart = searchSegment(x, line); + if (segStart == null) { + break; + } + final Segment segEnd = searchSegment(segStart.end + 1, line); + if (segEnd == null) { + break; + } + drawLine(segStart.end, segEnd.start, line); + x = segEnd.end + 1; + } + + } + } + + private void drawLine(int start, int end, int line) { + for (int i = start; i < end; i++) { + im.setRGB(i, line, underlineColor); + } + } + + private Segment searchSegment(final int i, final int line) { + for (int nb = i; nb < im.getWidth(); nb++) { + final Segment seg = searchSegmentExact(nb, line); + if (seg != null) { + return seg; + } + } + return null; + + } + + private Segment searchSegmentExact(final int i, final int line) { + for (int nb = 0; nb < 6; nb++) { + if (im.getRGB(i + nb, line) != searchedColor) { + return null; + } + } + for (int end = i; end < im.getWidth(); end++) { + if (im.getRGB(end, line) != searchedColor) { + return new Segment(i, end - 1); + } + } + return new Segment(i, im.getWidth() - 1); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/UnderlineTrickEps.java b/src/net/sourceforge/plantuml/cucadiagram/dot/UnderlineTrickEps.java new file mode 100644 index 000000000..a5014966e --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/UnderlineTrickEps.java @@ -0,0 +1,92 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3829 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class UnderlineTrickEps { + + private final StringBuilder result = new StringBuilder(); + + public UnderlineTrickEps(String eps) { + final List list = new ArrayList(); + StringTokenizer st = new StringTokenizer(eps, "\n"); + while (st.hasMoreTokens()) { + final String s = st.nextToken(); + list.add(s); + if (s.contains("(_!)")) { + final String other = list.get(list.size() - 4); + final String modified = changeToUnderscore(other); + if (modified != null) { + list.add(list.size() - 4, modified); + } + } + } + + for (String s : list) { + result.append(s); + result.append('\n'); + } + } + + static String changeToUnderscore(String s) { + final Pattern p = Pattern.compile("\\((.*)\\)"); + final Matcher m = p.matcher(s); + + final StringBuffer result = new StringBuffer(); + + if (m.find() == false) { + return null; + } + + final StringBuilder underscores = new StringBuilder("("); + for (int i = 0; i < m.group(1).length(); i++) { + underscores.append('_'); + } + underscores.append(')'); + + m.appendReplacement(result, underscores.toString()); + m.appendTail(result); + return result.toString(); + } + + public String getString() { + return result.toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/Unlazy.java b/src/net/sourceforge/plantuml/cucadiagram/dot/Unlazy.java new file mode 100644 index 000000000..286d6fc34 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/Unlazy.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3977 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +public class Unlazy implements Lazy { + + private final O data; + + public Unlazy(O data) { + this.data = data; + } + + public O getNow() { + return data; + } +} diff --git a/src/net/sourceforge/plantuml/eggs/EggUtils.java b/src/net/sourceforge/plantuml/eggs/EggUtils.java new file mode 100644 index 000000000..d172fe280 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/EggUtils.java @@ -0,0 +1,98 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.math.BigInteger; + +public class EggUtils { + + public static String fromByteArrays(byte data[]) { + final StringBuilder sb = new StringBuilder(); + for (byte b : data) { + final String hex = Integer.toHexString(b & 0xFF); + if (hex.length() == 1) { + sb.append('0'); + } + sb.append(hex); + } + return sb.toString(); + } + + public static byte[] toByteArrays(String s) { + final byte[] result = new byte[s.length() / 2]; + for (int i = 0; i < result.length; i++) { + result[i] = (byte) Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16); + } + return result; + } + + public static BigInteger fromSecretSentence(String s) { + BigInteger result = BigInteger.ZERO; + final BigInteger twentySix = BigInteger.valueOf(26); + s = s.replace('\u00E9', 'e'); + s = s.replace('\u00EA', 'e'); + for (char c : s.toCharArray()) { + final int num = convertChar(c); + if (num != -1) { + result = result.multiply(twentySix); + result = result.add(BigInteger.valueOf(num)); + + } + } + return result; + + } + + private static int convertChar(char c) { + c = Character.toLowerCase(c); + if (c >= 'a' && c <= 'z') { + return c - 'a'; + } + return -1; + } + + public static byte[] xor(byte data[], byte key[]) { + final byte[] result = new byte[data.length]; + int pos = 0; + for (int i = 0; i < result.length; i++) { + result[i] = (byte) (data[i] ^ key[pos++]); + if (pos == key.length) { + pos = 0; + } + + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/GraphicsPath.java b/src/net/sourceforge/plantuml/eggs/GraphicsPath.java new file mode 100644 index 000000000..bff654ebf --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/GraphicsPath.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; + +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.ugraphic.UMotif; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; + +public class GraphicsPath { + + private final String path; + + // private final Font numberFont = new Font("SansSerif", Font.BOLD, 20); + // private final Font font = new Font("SansSerif", Font.PLAIN, 11); + + public GraphicsPath(String path) { + this.path = path; + } + + public void writeImage(OutputStream os) throws IOException { + final BufferedImage im = createImage(); + PngIO.write(im, os); + } + + private BufferedImage createImage() { + final EmptyImageBuilder builder = new EmptyImageBuilder(50, 50, + Color.WHITE); + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + final UGraphicG2d ug = new UGraphicG2d(g2d, im); + ug.getParam().setColor(Color.BLACK); + final UMotif motif = new UMotif(path); + motif.drawHorizontal(ug, 20, 20, 1); + + g2d.dispose(); + return im; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemEgg.java b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java new file mode 100644 index 000000000..91a61b721 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java @@ -0,0 +1,88 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4984 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.awt.Color; +import java.awt.Font; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.GraphicStrings; + +public class PSystemEgg extends AbstractPSystem { + + private final List strings = new ArrayList(); + + PSystemEgg(String sentence) { + final StringTokenizer st = new StringTokenizer(sentence, "|"); + while (st.hasMoreTokens()) { + strings.add(st.nextToken()); + } + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + getGraphicStrings().writeImage(os, fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getGraphicStrings().writeImage(os, fileFormat); + } + + private GraphicStrings getGraphicStrings() throws IOException { + final Font font = new Font("SansSerif", Font.PLAIN, 12); + return new GraphicStrings(strings, font, Color.BLACK, Color.WHITE, false); + } + + public String getDescription() { + return "(Easter Eggs)"; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemEggFactory.java b/src/net/sourceforge/plantuml/eggs/PSystemEggFactory.java new file mode 100644 index 000000000..d77ba64fd --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemEggFactory.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemEggFactory implements PSystemBasicFactory { + + private PSystemEgg system; + + public PSystemEggFactory() { + reset(); + } + + public void reset() { + } + + final static private List all = Arrays + .asList( + EggUtils + .toByteArrays("56092d35fce86a0dd88047a766c1d6541a7c5fd5ba212fa02db9a32a463422febd71a75a934eb135dec7d6c6325ddd17fd2fa437eba863462b28e3e92514998306a72790d93501335ed6b1262ea46ab79573142c28f8e92508978255a533d9cf7903394f9ab73a33b230a2b273033633adf16044888243b92f9bd8351f3d4f9aa2302fb264afa37546368424fa6a07919152bd2990d935092e49d9a02038b437aeb528"), + EggUtils.toByteArrays("421e5b773c5df733a1194f716f18e8842155196b3b")); + + public boolean executeLine(String line) { + try { + for (byte[] crypted : all) { + final SentenceDecoder decoder = new SentenceDecoder(line, crypted); + if (decoder.isOk()) { + system = new PSystemEgg(decoder.getSecret()); + return true; + } + } + } catch (UnsupportedEncodingException e) { + return false; + } + + return false; + } + + public PSystemEgg getSystem() { + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemLost.java b/src/net/sourceforge/plantuml/eggs/PSystemLost.java new file mode 100644 index 000000000..ee593da1c --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemLost.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4041 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.awt.Color; +import java.awt.Font; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.GraphicStrings; + +public class PSystemLost extends AbstractPSystem { + + private final List strings = new ArrayList(); + + public PSystemLost() { + strings.add("Thank you for choosing Oceanic Airlines."); + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + getGraphicStrings().writeImage(os, fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getGraphicStrings().writeImage(os, fileFormat); + } + + private GraphicStrings getGraphicStrings() throws IOException { + final Font font = new Font("SansSerif", Font.PLAIN, 12); + return new GraphicStrings(strings, font, Color.BLACK, Color.WHITE, null, null, false); + } + + public String getDescription() { + return "(Lost)"; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemLostFactory.java b/src/net/sourceforge/plantuml/eggs/PSystemLostFactory.java new file mode 100644 index 000000000..fa6cc502a --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemLostFactory.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemLostFactory implements PSystemBasicFactory { + + private PSystemLost system; + + public PSystemLostFactory() { + reset(); + } + + public void reset() { + } + + public boolean executeLine(String line) { + if (line.matches("^4\\D+8\\D+15\\D+16\\D+23\\D+42")) { + system = new PSystemLost(); + return true; + } + return false; + } + + public PSystemLost getSystem() { + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemPath.java b/src/net/sourceforge/plantuml/eggs/PSystemPath.java new file mode 100644 index 000000000..ac9144ddd --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemPath.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4041 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; + +public class PSystemPath extends AbstractPSystem { + + private final GraphicsPath path; + + public PSystemPath(String s) { + this.path = new GraphicsPath(s); + } + + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + path.writeImage(os); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + path.writeImage(os); + } + + public String getDescription() { + return "(Path)"; + } + + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemPathFactory.java b/src/net/sourceforge/plantuml/eggs/PSystemPathFactory.java new file mode 100644 index 000000000..fe3c6d3a2 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemPathFactory.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemPathFactory implements PSystemBasicFactory { + + private PSystemPath system; + + public PSystemPathFactory() { + reset(); + } + + public void reset() { + } + + final private static Pattern p = Pattern + .compile("(?i)^path\\s+([0-9A-Za-z]+)$"); + + public boolean executeLine(String line) { + final Matcher m = p.matcher(line); + if (m.find() == false) { + return false; + } + system = new PSystemPath(m.group(1)); + return true; + } + + public PSystemPath getSystem() { + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java new file mode 100644 index 000000000..2d7d4fbcc --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java @@ -0,0 +1,470 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4041 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.awt.Color; +import java.awt.Font; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.GraphicPosition; +import net.sourceforge.plantuml.graphic.GraphicStrings; + +public class PSystemRIP extends AbstractPSystem { + + private final List strings = new ArrayList(); + private final BufferedImage image; + + public PSystemRIP() throws IOException { + strings.add(" To my Grandfather,"); + strings.add(" A mon grand-pere,"); + strings.add(" "); + strings.add(" Jean CANOUET"); + strings.add(" "); + strings.add(" 31-OCT-1921 (Neuilly-Sur-Seine, France)"); + strings.add(" 15-SEP-2009 (Nanterre, France)"); + strings.add(" "); + strings.add(" Requiescat In Pace"); + strings.add(" "); + + final InputStream is = new ByteArrayInputStream(imm); + image = ImageIO.read(is); + is.close(); + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + getGraphicStrings().writeImage(os, fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getGraphicStrings().writeImage(os, fileFormat); + } + + private GraphicStrings getGraphicStrings() throws IOException { + final Font font = new Font("SansSerif", Font.PLAIN, 12); + return new GraphicStrings(strings, font, Color.BLACK, Color.WHITE, image, GraphicPosition.BOTTOM, false); + } + + public String getDescription() { + return "(RIP)"; + } + + private static final byte imm[] = new byte[] { (byte) 255, (byte) 216, (byte) 255, (byte) 224, (byte) 0, (byte) 16, + (byte) 74, (byte) 70, (byte) 73, (byte) 70, (byte) 0, (byte) 1, (byte) 1, (byte) 1, (byte) 2, (byte) 88, + (byte) 2, (byte) 88, (byte) 0, (byte) 0, (byte) 255, (byte) 219, (byte) 0, (byte) 67, (byte) 0, (byte) 13, + (byte) 9, (byte) 10, (byte) 11, (byte) 10, (byte) 8, (byte) 13, (byte) 11, (byte) 10, (byte) 11, (byte) 14, + (byte) 14, (byte) 13, (byte) 15, (byte) 19, (byte) 32, (byte) 21, (byte) 19, (byte) 18, (byte) 18, + (byte) 19, (byte) 39, (byte) 28, (byte) 30, (byte) 23, (byte) 32, (byte) 46, (byte) 41, (byte) 49, + (byte) 48, (byte) 46, (byte) 41, (byte) 45, (byte) 44, (byte) 51, (byte) 58, (byte) 74, (byte) 62, + (byte) 51, (byte) 54, (byte) 70, (byte) 55, (byte) 44, (byte) 45, (byte) 64, (byte) 87, (byte) 65, + (byte) 70, (byte) 76, (byte) 78, (byte) 82, (byte) 83, (byte) 82, (byte) 50, (byte) 62, (byte) 90, + (byte) 97, (byte) 90, (byte) 80, (byte) 96, (byte) 74, (byte) 81, (byte) 82, (byte) 79, (byte) 255, + (byte) 219, (byte) 0, (byte) 67, (byte) 1, (byte) 14, (byte) 14, (byte) 14, (byte) 19, (byte) 17, + (byte) 19, (byte) 38, (byte) 21, (byte) 21, (byte) 38, (byte) 79, (byte) 53, (byte) 45, (byte) 53, + (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, + (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, + (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, + (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, + (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, + (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 79, (byte) 255, (byte) 192, (byte) 0, (byte) 17, + (byte) 8, (byte) 0, (byte) 135, (byte) 0, (byte) 162, (byte) 3, (byte) 1, (byte) 34, (byte) 0, (byte) 2, + (byte) 17, (byte) 1, (byte) 3, (byte) 17, (byte) 1, (byte) 255, (byte) 196, (byte) 0, (byte) 31, (byte) 0, + (byte) 0, (byte) 1, (byte) 5, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 0, + (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 2, (byte) 3, + (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11, (byte) 255, (byte) 196, + (byte) 0, (byte) 181, (byte) 16, (byte) 0, (byte) 2, (byte) 1, (byte) 3, (byte) 3, (byte) 2, (byte) 4, + (byte) 3, (byte) 5, (byte) 5, (byte) 4, (byte) 4, (byte) 0, (byte) 0, (byte) 1, (byte) 125, (byte) 1, + (byte) 2, (byte) 3, (byte) 0, (byte) 4, (byte) 17, (byte) 5, (byte) 18, (byte) 33, (byte) 49, (byte) 65, + (byte) 6, (byte) 19, (byte) 81, (byte) 97, (byte) 7, (byte) 34, (byte) 113, (byte) 20, (byte) 50, + (byte) 129, (byte) 145, (byte) 161, (byte) 8, (byte) 35, (byte) 66, (byte) 177, (byte) 193, (byte) 21, + (byte) 82, (byte) 209, (byte) 240, (byte) 36, (byte) 51, (byte) 98, (byte) 114, (byte) 130, (byte) 9, + (byte) 10, (byte) 22, (byte) 23, (byte) 24, (byte) 25, (byte) 26, (byte) 37, (byte) 38, (byte) 39, + (byte) 40, (byte) 41, (byte) 42, (byte) 52, (byte) 53, (byte) 54, (byte) 55, (byte) 56, (byte) 57, + (byte) 58, (byte) 67, (byte) 68, (byte) 69, (byte) 70, (byte) 71, (byte) 72, (byte) 73, (byte) 74, + (byte) 83, (byte) 84, (byte) 85, (byte) 86, (byte) 87, (byte) 88, (byte) 89, (byte) 90, (byte) 99, + (byte) 100, (byte) 101, (byte) 102, (byte) 103, (byte) 104, (byte) 105, (byte) 106, (byte) 115, (byte) 116, + (byte) 117, (byte) 118, (byte) 119, (byte) 120, (byte) 121, (byte) 122, (byte) 131, (byte) 132, (byte) 133, + (byte) 134, (byte) 135, (byte) 136, (byte) 137, (byte) 138, (byte) 146, (byte) 147, (byte) 148, (byte) 149, + (byte) 150, (byte) 151, (byte) 152, (byte) 153, (byte) 154, (byte) 162, (byte) 163, (byte) 164, (byte) 165, + (byte) 166, (byte) 167, (byte) 168, (byte) 169, (byte) 170, (byte) 178, (byte) 179, (byte) 180, (byte) 181, + (byte) 182, (byte) 183, (byte) 184, (byte) 185, (byte) 186, (byte) 194, (byte) 195, (byte) 196, (byte) 197, + (byte) 198, (byte) 199, (byte) 200, (byte) 201, (byte) 202, (byte) 210, (byte) 211, (byte) 212, (byte) 213, + (byte) 214, (byte) 215, (byte) 216, (byte) 217, (byte) 218, (byte) 225, (byte) 226, (byte) 227, (byte) 228, + (byte) 229, (byte) 230, (byte) 231, (byte) 232, (byte) 233, (byte) 234, (byte) 241, (byte) 242, (byte) 243, + (byte) 244, (byte) 245, (byte) 246, (byte) 247, (byte) 248, (byte) 249, (byte) 250, (byte) 255, (byte) 196, + (byte) 0, (byte) 31, (byte) 1, (byte) 0, (byte) 3, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, + (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, + (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, + (byte) 11, (byte) 255, (byte) 196, (byte) 0, (byte) 181, (byte) 17, (byte) 0, (byte) 2, (byte) 1, (byte) 2, + (byte) 4, (byte) 4, (byte) 3, (byte) 4, (byte) 7, (byte) 5, (byte) 4, (byte) 4, (byte) 0, (byte) 1, + (byte) 2, (byte) 119, (byte) 0, (byte) 1, (byte) 2, (byte) 3, (byte) 17, (byte) 4, (byte) 5, (byte) 33, + (byte) 49, (byte) 6, (byte) 18, (byte) 65, (byte) 81, (byte) 7, (byte) 97, (byte) 113, (byte) 19, + (byte) 34, (byte) 50, (byte) 129, (byte) 8, (byte) 20, (byte) 66, (byte) 145, (byte) 161, (byte) 177, + (byte) 193, (byte) 9, (byte) 35, (byte) 51, (byte) 82, (byte) 240, (byte) 21, (byte) 98, (byte) 114, + (byte) 209, (byte) 10, (byte) 22, (byte) 36, (byte) 52, (byte) 225, (byte) 37, (byte) 241, (byte) 23, + (byte) 24, (byte) 25, (byte) 26, (byte) 38, (byte) 39, (byte) 40, (byte) 41, (byte) 42, (byte) 53, + (byte) 54, (byte) 55, (byte) 56, (byte) 57, (byte) 58, (byte) 67, (byte) 68, (byte) 69, (byte) 70, + (byte) 71, (byte) 72, (byte) 73, (byte) 74, (byte) 83, (byte) 84, (byte) 85, (byte) 86, (byte) 87, + (byte) 88, (byte) 89, (byte) 90, (byte) 99, (byte) 100, (byte) 101, (byte) 102, (byte) 103, (byte) 104, + (byte) 105, (byte) 106, (byte) 115, (byte) 116, (byte) 117, (byte) 118, (byte) 119, (byte) 120, (byte) 121, + (byte) 122, (byte) 130, (byte) 131, (byte) 132, (byte) 133, (byte) 134, (byte) 135, (byte) 136, (byte) 137, + (byte) 138, (byte) 146, (byte) 147, (byte) 148, (byte) 149, (byte) 150, (byte) 151, (byte) 152, (byte) 153, + (byte) 154, (byte) 162, (byte) 163, (byte) 164, (byte) 165, (byte) 166, (byte) 167, (byte) 168, (byte) 169, + (byte) 170, (byte) 178, (byte) 179, (byte) 180, (byte) 181, (byte) 182, (byte) 183, (byte) 184, (byte) 185, + (byte) 186, (byte) 194, (byte) 195, (byte) 196, (byte) 197, (byte) 198, (byte) 199, (byte) 200, (byte) 201, + (byte) 202, (byte) 210, (byte) 211, (byte) 212, (byte) 213, (byte) 214, (byte) 215, (byte) 216, (byte) 217, + (byte) 218, (byte) 226, (byte) 227, (byte) 228, (byte) 229, (byte) 230, (byte) 231, (byte) 232, (byte) 233, + (byte) 234, (byte) 242, (byte) 243, (byte) 244, (byte) 245, (byte) 246, (byte) 247, (byte) 248, (byte) 249, + (byte) 250, (byte) 255, (byte) 218, (byte) 0, (byte) 12, (byte) 3, (byte) 1, (byte) 0, (byte) 2, (byte) 17, + (byte) 3, (byte) 17, (byte) 0, (byte) 63, (byte) 0, (byte) 180, (byte) 48, (byte) 6, (byte) 69, (byte) 84, + (byte) 212, (byte) 135, (byte) 250, (byte) 49, (byte) 235, (byte) 214, (byte) 174, (byte) 116, (byte) 246, + (byte) 170, (byte) 154, (byte) 144, (byte) 205, (byte) 153, (byte) 61, (byte) 121, (byte) 21, (byte) 200, + (byte) 246, (byte) 61, (byte) 8, (byte) 124, (byte) 72, (byte) 202, (byte) 94, (byte) 7, (byte) 29, + (byte) 233, (byte) 24, (byte) 100, (byte) 127, (byte) 58, (byte) 114, (byte) 99, (byte) 181, (byte) 4, + (byte) 113, (byte) 222, (byte) 176, (byte) 59, (byte) 8, (byte) 226, (byte) 228, (byte) 103, (byte) 29, + (byte) 41, (byte) 177, (byte) 227, (byte) 127, (byte) 20, (byte) 228, (byte) 198, (byte) 211, (byte) 206, + (byte) 41, (byte) 163, (byte) 137, (byte) 61, (byte) 168, (byte) 1, (byte) 95, (byte) 168, (byte) 232, + (byte) 42, (byte) 212, (byte) 24, (byte) 242, (byte) 151, (byte) 57, (byte) 224, (byte) 246, (byte) 170, + (byte) 210, (byte) 18, (byte) 112, (byte) 42, (byte) 205, (byte) 191, (byte) 250, (byte) 159, (byte) 188, + (byte) 122, (byte) 211, (byte) 20, (byte) 182, (byte) 36, (byte) 7, (byte) 23, (byte) 72, (byte) 115, + (byte) 220, (byte) 113, (byte) 90, (byte) 135, (byte) 238, (byte) 140, (byte) 117, (byte) 205, (byte) 100, + (byte) 183, (byte) 19, (byte) 171, (byte) 99, (byte) 161, (byte) 28, (byte) 85, (byte) 249, (byte) 174, + (byte) 226, (byte) 133, (byte) 112, (byte) 207, (byte) 207, (byte) 160, (byte) 173, (byte) 32, (byte) 99, + (byte) 81, (byte) 55, (byte) 107, (byte) 22, (byte) 20, (byte) 117, (byte) 233, (byte) 214, (byte) 148, + (byte) 116, (byte) 108, (byte) 250, (byte) 214, (byte) 83, (byte) 106, (byte) 172, (byte) 14, (byte) 35, + (byte) 143, (byte) 143, (byte) 122, (byte) 106, (byte) 106, (byte) 115, (byte) 110, (byte) 249, (byte) 163, + (byte) 4, (byte) 103, (byte) 165, (byte) 105, (byte) 116, (byte) 79, (byte) 179, (byte) 145, (byte) 179, + (byte) 143, (byte) 148, (byte) 99, (byte) 138, (byte) 204, (byte) 214, (byte) 135, (byte) 203, (byte) 23, + (byte) 63, (byte) 197, (byte) 82, (byte) 195, (byte) 168, (byte) 71, (byte) 39, (byte) 13, (byte) 149, + (byte) 57, (byte) 232, (byte) 106, (byte) 13, (byte) 93, (byte) 131, (byte) 197, (byte) 27, (byte) 43, + (byte) 103, (byte) 230, (byte) 235, (byte) 69, (byte) 197, (byte) 20, (byte) 212, (byte) 181, (byte) 28, + (byte) 169, (byte) 38, (byte) 6, (byte) 8, (byte) 198, (byte) 61, (byte) 41, (byte) 205, (byte) 20, + (byte) 196, (byte) 13, (byte) 178, (byte) 1, (byte) 248, (byte) 81, (byte) 24, (byte) 118, (byte) 81, + (byte) 243, (byte) 246, (byte) 167, (byte) 180, (byte) 76, (byte) 64, (byte) 196, (byte) 173, (byte) 159, + (byte) 76, (byte) 212, (byte) 131, (byte) 96, (byte) 177, (byte) 200, (byte) 62, (byte) 83, (byte) 43, + (byte) 123, (byte) 226, (byte) 164, (byte) 17, (byte) 156, (byte) 99, (byte) 123, (byte) 126, (byte) 117, + (byte) 24, (byte) 140, (byte) 175, (byte) 222, (byte) 118, (byte) 231, (byte) 190, (byte) 105, (byte) 193, + (byte) 71, (byte) 77, (byte) 199, (byte) 241, (byte) 52, (byte) 196, (byte) 72, (byte) 34, (byte) 83, + (byte) 213, (byte) 155, (byte) 39, (byte) 142, (byte) 180, (byte) 162, (byte) 36, (byte) 201, (byte) 201, + (byte) 63, (byte) 157, (byte) 51, (byte) 9, (byte) 158, (byte) 88, (byte) 115, (byte) 239, (byte) 78, + (byte) 81, (byte) 24, (byte) 39, (byte) 230, (byte) 20, (byte) 132, (byte) 39, (byte) 151, (byte) 31, + (byte) 181, (byte) 20, (byte) 252, (byte) 197, (byte) 234, (byte) 40, (byte) 160, (byte) 46, (byte) 76, + (byte) 7, (byte) 168, (byte) 170, (byte) 218, (byte) 128, (byte) 255, (byte) 0, (byte) 67, (byte) 127, + (byte) 194, (byte) 174, (byte) 1, (byte) 199, (byte) 61, (byte) 42, (byte) 190, (byte) 160, (byte) 191, + (byte) 232, (byte) 114, (byte) 96, (byte) 83, (byte) 123, (byte) 10, (byte) 59, (byte) 163, (byte) 13, + (byte) 6, (byte) 6, (byte) 41, (byte) 89, (byte) 72, (byte) 247, (byte) 52, (byte) 168, (byte) 164, + (byte) 119, (byte) 193, (byte) 167, (byte) 50, (byte) 156, (byte) 26, (byte) 231, (byte) 108, (byte) 236, + (byte) 34, (byte) 140, (byte) 114, (byte) 221, (byte) 51, (byte) 81, (byte) 168, (byte) 30, (byte) 103, + (byte) 34, (byte) 165, (byte) 139, (byte) 134, (byte) 61, (byte) 233, (byte) 164, (byte) 226, (byte) 83, + (byte) 199, (byte) 90, (byte) 10, (byte) 65, (byte) 42, (byte) 227, (byte) 233, (byte) 86, (byte) 109, + (byte) 128, (byte) 48, (byte) 231, (byte) 112, (byte) 94, (byte) 123, (byte) 213, (byte) 121, (byte) 58, + (byte) 116, (byte) 233, (byte) 79, (byte) 50, (byte) 8, (byte) 236, (byte) 152, (byte) 224, (byte) 18, + (byte) 125, (byte) 104, (byte) 90, (byte) 147, (byte) 45, (byte) 136, (byte) 238, (byte) 231, (byte) 253, + (byte) 246, (byte) 200, (byte) 136, (byte) 220, (byte) 58, (byte) 181, (byte) 49, (byte) 85, (byte) 187, + (byte) 245, (byte) 61, (byte) 205, (byte) 71, (byte) 2, (byte) 28, (byte) 100, (byte) 247, (byte) 171, + (byte) 208, (byte) 71, (byte) 131, (byte) 156, (byte) 113, (byte) 90, (byte) 109, (byte) 161, (byte) 73, + (byte) 13, (byte) 138, (byte) 14, (byte) 121, (byte) 228, (byte) 85, (byte) 143, (byte) 32, (byte) 40, + (byte) 199, (byte) 74, (byte) 181, (byte) 111, (byte) 16, (byte) 61, (byte) 112, (byte) 125, (byte) 51, + (byte) 83, (byte) 203, (byte) 26, (byte) 4, (byte) 31, (byte) 39, (byte) 228, (byte) 105, (byte) 1, + (byte) 143, (byte) 44, (byte) 56, (byte) 233, (byte) 154, (byte) 169, (byte) 59, (byte) 72, (byte) 19, + (byte) 110, (byte) 114, (byte) 1, (byte) 200, (byte) 21, (byte) 181, (byte) 34, (byte) 140, (byte) 30, + (byte) 0, (byte) 250, (byte) 86, (byte) 124, (byte) 241, (byte) 130, (byte) 50, (byte) 71, (byte) 229, + (byte) 66, (byte) 97, (byte) 107, (byte) 133, (byte) 165, (byte) 202, (byte) 200, (byte) 161, (byte) 93, + (byte) 176, (byte) 122, (byte) 114, (byte) 106, (byte) 198, (byte) 3, (byte) 30, (byte) 95, (byte) 233, + (byte) 205, (byte) 99, (byte) 74, (byte) 165, (byte) 36, (byte) 201, (byte) 30, (byte) 226, (byte) 181, + (byte) 45, (byte) 36, (byte) 134, (byte) 120, (byte) 182, (byte) 202, (byte) 16, (byte) 17, (byte) 222, + (byte) 180, (byte) 49, (byte) 156, (byte) 109, (byte) 169, (byte) 58, (byte) 136, (byte) 192, (byte) 193, + (byte) 97, (byte) 249, (byte) 212, (byte) 170, (byte) 177, (byte) 131, (byte) 156, (byte) 138, (byte) 114, + (byte) 8, (byte) 66, (byte) 241, (byte) 183, (byte) 138, (byte) 148, (byte) 24, (byte) 123, (byte) 117, + (byte) 250, (byte) 80, (byte) 101, (byte) 113, (byte) 170, (byte) 98, (byte) 235, (byte) 149, (byte) 247, + (byte) 226, (byte) 156, (byte) 101, (byte) 128, (byte) 1, (byte) 128, (byte) 51, (byte) 158, (byte) 160, + (byte) 82, (byte) 230, (byte) 48, (byte) 49, (byte) 131, (byte) 207, (byte) 160, (byte) 163, (byte) 204, + (byte) 78, (byte) 56, (byte) 63, (byte) 247, (byte) 205, (byte) 50, (byte) 70, (byte) 249, (byte) 145, + (byte) 255, (byte) 0, (byte) 181, (byte) 255, (byte) 0, (byte) 124, (byte) 209, (byte) 78, (byte) 243, + (byte) 71, (byte) 247, (byte) 91, (byte) 242, (byte) 162, (byte) 150, (byte) 131, (byte) 47, (byte) 99, + (byte) 143, (byte) 173, (byte) 87, (byte) 191, (byte) 81, (byte) 246, (byte) 73, (byte) 51, (byte) 233, + (byte) 87, (byte) 48, (byte) 14, (byte) 122, (byte) 213, (byte) 123, (byte) 209, (byte) 254, (byte) 137, + (byte) 39, (byte) 166, (byte) 41, (byte) 189, (byte) 136, (byte) 142, (byte) 232, (byte) 231, (byte) 208, + (byte) 102, (byte) 158, (byte) 220, (byte) 28, (byte) 10, (byte) 106, (byte) 227, (byte) 138, (byte) 151, + (byte) 4, (byte) 142, (byte) 245, (byte) 204, (byte) 118, (byte) 144, (byte) 32, (byte) 204, (byte) 135, + (byte) 53, (byte) 27, (byte) 224, (byte) 75, (byte) 199, (byte) 173, (byte) 74, (byte) 56, (byte) 147, + (byte) 6, (byte) 152, (byte) 227, (byte) 247, (byte) 216, (byte) 52, (byte) 13, (byte) 4, (byte) 131, + (byte) 229, (byte) 206, (byte) 42, (byte) 180, (byte) 161, (byte) 152, (byte) 172, (byte) 125, (byte) 135, + (byte) 38, (byte) 174, (byte) 74, (byte) 0, (byte) 66, (byte) 7, (byte) 165, (byte) 64, (byte) 235, + (byte) 209, (byte) 179, (byte) 205, (byte) 84, (byte) 55, (byte) 6, (byte) 75, (byte) 12, (byte) 125, + (byte) 1, (byte) 206, (byte) 49, (byte) 82, (byte) 77, (byte) 113, (byte) 228, (byte) 97, (byte) 81, + (byte) 55, (byte) 53, (byte) 62, (byte) 220, (byte) 101, (byte) 50, (byte) 8, (byte) 233, (byte) 82, + (byte) 89, (byte) 36, (byte) 127, (byte) 104, (byte) 221, (byte) 112, (byte) 192, (byte) 51, (byte) 30, + (byte) 51, (byte) 218, (byte) 173, (byte) 110, (byte) 13, (byte) 216, (byte) 91, (byte) 75, (byte) 240, + (byte) 236, (byte) 18, (byte) 96, (byte) 87, (byte) 60, (byte) 100, (byte) 138, (byte) 213, (byte) 16, + (byte) 130, (byte) 157, (byte) 141, (byte) 23, (byte) 246, (byte) 118, (byte) 182, (byte) 234, (byte) 140, + (byte) 204, (byte) 24, (byte) 48, (byte) 4, (byte) 48, (byte) 82, (byte) 42, (byte) 72, (byte) 118, + (byte) 199, (byte) 18, (byte) 146, (byte) 202, (byte) 85, (byte) 135, (byte) 20, (byte) 89, (byte) 18, + (byte) 165, (byte) 116, (byte) 103, (byte) 94, (byte) 98, (byte) 221, (byte) 119, (byte) 177, (byte) 206, + (byte) 122, (byte) 10, (byte) 200, (byte) 123, (byte) 208, (byte) 220, (byte) 52, (byte) 100, (byte) 15, + (byte) 90, (byte) 222, (byte) 146, (byte) 15, (byte) 58, (byte) 38, (byte) 157, (byte) 212, (byte) 178, + (byte) 47, (byte) 124, (byte) 116, (byte) 172, (byte) 233, (byte) 252, (byte) 150, (byte) 66, (byte) 172, + (byte) 128, (byte) 46, (byte) 113, (byte) 144, (byte) 59, (byte) 209, (byte) 161, (byte) 92, (byte) 198, + (byte) 93, (byte) 202, (byte) 228, (byte) 43, (byte) 1, (byte) 197, (byte) 45, (byte) 140, (byte) 209, + (byte) 37, (byte) 198, (byte) 37, (byte) 25, (byte) 83, (byte) 198, (byte) 49, (byte) 82, (byte) 204, + (byte) 134, (byte) 37, (byte) 10, (byte) 72, (byte) 62, (byte) 135, (byte) 218, (byte) 170, (byte) 194, + (byte) 234, (byte) 147, (byte) 169, (byte) 35, (byte) 60, (byte) 250, (byte) 85, (byte) 33, (byte) 61, + (byte) 81, (byte) 209, (byte) 164, (byte) 208, (byte) 237, (byte) 218, (byte) 128, (byte) 227, (byte) 217, + (byte) 77, (byte) 60, (byte) 72, (byte) 167, (byte) 162, (byte) 177, (byte) 255, (byte) 0, (byte) 128, + (byte) 154, (byte) 72, (byte) 231, (byte) 27, (byte) 70, (byte) 17, (byte) 200, (byte) 199, (byte) 101, + (byte) 169, (byte) 145, (byte) 201, (byte) 255, (byte) 0, (byte) 150, (byte) 111, (byte) 84, (byte) 114, + (byte) 49, (byte) 155, (byte) 207, (byte) 64, (byte) 173, (byte) 255, (byte) 0, (byte) 124, (byte) 208, + (byte) 95, (byte) 166, (byte) 99, (byte) 111, (byte) 202, (byte) 165, (byte) 220, (byte) 199, (byte) 164, + (byte) 109, (byte) 75, (byte) 185, (byte) 207, (byte) 30, (byte) 89, (byte) 252, (byte) 233, (byte) 8, + (byte) 103, (byte) 154, (byte) 223, (byte) 243, (byte) 204, (byte) 254, (byte) 84, (byte) 83, (byte) 240, + (byte) 255, (byte) 0, (byte) 243, (byte) 207, (byte) 245, (byte) 162, (byte) 139, (byte) 129, (byte) 108, + (byte) 142, (byte) 106, (byte) 43, (byte) 197, (byte) 205, (byte) 164, (byte) 131, (byte) 167, (byte) 202, + (byte) 106, (byte) 206, (byte) 61, (byte) 122, (byte) 212, (byte) 87, (byte) 35, (byte) 54, (byte) 210, + (byte) 103, (byte) 251, (byte) 166, (byte) 155, (byte) 216, (byte) 148, (byte) 245, (byte) 57, (byte) 164, + (byte) 83, (byte) 145, (byte) 215, (byte) 138, (byte) 148, (byte) 1, (byte) 154, (byte) 106, (byte) 14, + (byte) 112, (byte) 106, (byte) 80, (byte) 56, (byte) 237, (byte) 154, (byte) 229, (byte) 103, (byte) 109, + (byte) 202, (byte) 216, (byte) 253, (byte) 233, (byte) 166, (byte) 203, (byte) 254, (byte) 180, (byte) 26, + (byte) 148, (byte) 2, (byte) 37, (byte) 250, (byte) 211, (byte) 102, (byte) 95, (byte) 222, (byte) 140, + (byte) 154, (byte) 16, (byte) 192, (byte) 168, (byte) 96, (byte) 42, (byte) 213, (byte) 212, (byte) 17, + (byte) 164, (byte) 33, (byte) 112, (byte) 8, (byte) 198, (byte) 106, (byte) 187, (byte) 175, (byte) 203, + (byte) 212, (byte) 226, (byte) 172, (byte) 135, (byte) 13, (byte) 102, (byte) 197, (byte) 190, (byte) 241, + (byte) 92, (byte) 125, (byte) 106, (byte) 224, (byte) 50, (byte) 188, (byte) 16, (byte) 70, (byte) 223, + (byte) 42, (byte) 147, (byte) 130, (byte) 123, (byte) 28, (byte) 84, (byte) 255, (byte) 0, (byte) 101, + (byte) 119, (byte) 159, (byte) 129, (byte) 140, (byte) 112, (byte) 42, (byte) 27, (byte) 77, (byte) 194, + (byte) 69, (byte) 29, (byte) 171, (byte) 106, (byte) 37, (byte) 87, (byte) 56, (byte) 12, (byte) 1, + (byte) 199, (byte) 122, (byte) 173, (byte) 68, (byte) 244, (byte) 27, (byte) 112, (byte) 215, (byte) 18, + (byte) 90, (byte) 195, (byte) 28, (byte) 164, (byte) 58, (byte) 196, (byte) 48, (byte) 6, (byte) 59, + (byte) 85, (byte) 41, (byte) 110, (byte) 30, (byte) 17, (byte) 177, (byte) 85, (byte) 126, (byte) 113, + (byte) 223, (byte) 156, (byte) 86, (byte) 156, (byte) 144, (byte) 21, (byte) 66, (byte) 210, (byte) 55, + (byte) 3, (byte) 144, (byte) 23, (byte) 189, (byte) 101, (byte) 198, (byte) 130, (byte) 123, (byte) 163, + (byte) 185, (byte) 130, (byte) 250, (byte) 3, (byte) 218, (byte) 158, (byte) 251, (byte) 132, (byte) 82, + (byte) 38, (byte) 180, (byte) 184, (byte) 157, (byte) 108, (byte) 165, (byte) 137, (byte) 27, (byte) 247, + (byte) 114, (byte) 12, (byte) 50, (byte) 213, (byte) 9, (byte) 163, (byte) 85, (byte) 93, (byte) 170, + (byte) 8, (byte) 238, (byte) 125, (byte) 234, (byte) 218, (byte) 68, (byte) 233, (byte) 118, (byte) 99, + (byte) 71, (byte) 24, (byte) 60, (byte) 143, (byte) 66, (byte) 105, (byte) 243, (byte) 71, (byte) 34, + (byte) 130, (byte) 90, (byte) 62, (byte) 71, (byte) 189, (byte) 14, (byte) 227, (byte) 178, (byte) 76, + (byte) 206, (byte) 146, (byte) 47, (byte) 58, (byte) 84, (byte) 80, (byte) 6, (byte) 91, (byte) 214, + (byte) 179, (byte) 221, (byte) 190, (byte) 207, (byte) 119, (byte) 141, (byte) 155, (byte) 130, (byte) 55, + (byte) 74, (byte) 189, (byte) 44, (byte) 158, (byte) 84, (byte) 193, (byte) 240, (byte) 1, (byte) 0, + (byte) 145, (byte) 143, (byte) 90, (byte) 207, (byte) 11, (byte) 52, (byte) 243, (byte) 240, (byte) 187, + (byte) 153, (byte) 143, (byte) 65, (byte) 84, (byte) 132, (byte) 246, (byte) 58, (byte) 107, (byte) 121, + (byte) 76, (byte) 145, (byte) 171, (byte) 136, (byte) 142, (byte) 8, (byte) 233, (byte) 154, (byte) 156, + (byte) 23, (byte) 255, (byte) 0, (byte) 158, (byte) 120, (byte) 252, (byte) 106, (byte) 59, (byte) 88, + (byte) 231, (byte) 72, (byte) 85, (byte) 10, (byte) 32, (byte) 192, (byte) 171, (byte) 24, (byte) 151, + (byte) 31, (byte) 193, (byte) 154, (byte) 163, (byte) 141, (byte) 140, (byte) 5, (byte) 241, (byte) 247, + (byte) 7, (byte) 231, (byte) 74, (byte) 60, (byte) 206, (byte) 161, (byte) 71, (byte) 231, (byte) 78, + (byte) 219, (byte) 47, (byte) 251, (byte) 20, (byte) 170, (byte) 178, (byte) 231, (byte) 239, (byte) 47, + (byte) 229, (byte) 64, (byte) 134, (byte) 252, (byte) 222, (byte) 139, (byte) 249, (byte) 209, (byte) 82, + (byte) 121, (byte) 114, (byte) 255, (byte) 0, (byte) 121, (byte) 104, (byte) 164, (byte) 23, (byte) 44, + (byte) 149, (byte) 39, (byte) 165, (byte) 71, (byte) 58, (byte) 159, (byte) 33, (byte) 198, (byte) 63, + (byte) 132, (byte) 212, (byte) 248, (byte) 7, (byte) 138, (byte) 108, (byte) 171, (byte) 251, (byte) 166, + (byte) 250, (byte) 98, (byte) 171, (byte) 161, (byte) 11, (byte) 115, (byte) 150, (byte) 140, (byte) 124, + (byte) 220, (byte) 84, (byte) 219, (byte) 121, (byte) 166, (byte) 42, (byte) 146, (byte) 216, (byte) 29, + (byte) 141, (byte) 78, (byte) 163, (byte) 154, (byte) 228, (byte) 123, (byte) 157, (byte) 197, (byte) 82, + (byte) 15, (byte) 152, (byte) 41, (byte) 179, (byte) 175, (byte) 206, (byte) 9, (byte) 169, (byte) 153, + (byte) 79, (byte) 154, (byte) 41, (byte) 147, (byte) 174, (byte) 25, (byte) 73, (byte) 206, (byte) 40, + (byte) 24, (byte) 99, (byte) 9, (byte) 142, (byte) 105, (byte) 208, (byte) 32, (byte) 101, (byte) 37, + (byte) 219, (byte) 104, (byte) 3, (byte) 34, (byte) 159, (byte) 183, (byte) 40, (byte) 112, (byte) 57, + (byte) 237, (byte) 87, (byte) 108, (byte) 236, (byte) 100, (byte) 40, (byte) 124, (byte) 193, (byte) 141, + (byte) 195, (byte) 165, (byte) 105, (byte) 74, (byte) 46, (byte) 79, (byte) 66, (byte) 39, (byte) 53, + (byte) 21, (byte) 118, (byte) 80, (byte) 183, (byte) 31, (byte) 48, (byte) 30, (byte) 245, (byte) 173, + (byte) 110, (byte) 152, (byte) 249, (byte) 143, (byte) 65, (byte) 84, (byte) 163, (byte) 128, (byte) 195, + (byte) 115, (byte) 176, (byte) 245, (byte) 7, (byte) 154, (byte) 211, (byte) 141, (byte) 51, (byte) 149, + (byte) 238, (byte) 106, (byte) 154, (byte) 177, (byte) 92, (byte) 221, (byte) 72, (byte) 46, (byte) 238, + (byte) 55, (byte) 28, (byte) 100, (byte) 243, (byte) 85, (byte) 226, (byte) 183, (byte) 93, (byte) 187, + (byte) 152, (byte) 114, (byte) 122, (byte) 123, (byte) 83, (byte) 117, (byte) 8, (byte) 38, (byte) 102, + (byte) 45, (byte) 19, (byte) 99, (byte) 29, (byte) 133, (byte) 85, (byte) 84, (byte) 185, (byte) 85, + (byte) 206, (byte) 72, (byte) 230, (byte) 132, (byte) 104, (byte) 147, (byte) 104, (byte) 89, (byte) 3, + (byte) 67, (byte) 117, (byte) 149, (byte) 99, (byte) 128, (byte) 106, (byte) 244, (byte) 178, (byte) 9, + (byte) 34, (byte) 221, (byte) 237, (byte) 89, (byte) 66, (byte) 41, (byte) 158, (byte) 113, (byte) 184, + (byte) 182, (byte) 220, (byte) 242, (byte) 107, (byte) 96, (byte) 162, (byte) 139, (byte) 124, (byte) 142, + (byte) 167, (byte) 138, (byte) 24, (byte) 164, (byte) 236, (byte) 97, (byte) 94, (byte) 129, (byte) 146, + (byte) 9, (byte) 193, (byte) 199, (byte) 21, (byte) 14, (byte) 155, (byte) 230, (byte) 11, (byte) 164, + (byte) 219, (byte) 183, (byte) 35, (byte) 212, (byte) 113, (byte) 79, (byte) 212, (byte) 207, (byte) 250, + (byte) 70, (byte) 220, (byte) 227, (byte) 2, (byte) 173, (byte) 104, (byte) 214, (byte) 141, (byte) 33, + (byte) 105, (byte) 3, (byte) 225, (byte) 151, (byte) 167, (byte) 28, (byte) 85, (byte) 35, (byte) 57, + (byte) 187, (byte) 35, (byte) 106, (byte) 53, (byte) 159, (byte) 3, (byte) 123, (byte) 174, (byte) 125, + (byte) 133, (byte) 60, (byte) 71, (byte) 38, (byte) 57, (byte) 113, (byte) 159, (byte) 165, (byte) 34, + (byte) 197, (byte) 40, (byte) 31, (byte) 52, (byte) 205, (byte) 159, (byte) 165, (byte) 56, (byte) 198, + (byte) 248, (byte) 229, (byte) 216, (byte) 211, (byte) 57, (byte) 67, (byte) 99, (byte) 224, (byte) 130, + (byte) 252, (byte) 253, (byte) 41, (byte) 66, (byte) 201, (byte) 221, (byte) 248, (byte) 250, (byte) 81, + (byte) 229, (byte) 147, (byte) 140, (byte) 187, (byte) 82, (byte) 136, (byte) 207, (byte) 247, (byte) 219, + (byte) 31, (byte) 90, (byte) 96, (byte) 46, (byte) 195, (byte) 255, (byte) 0, (byte) 61, (byte) 13, + (byte) 20, (byte) 121, (byte) 63, (byte) 237, (byte) 55, (byte) 231, (byte) 69, (byte) 23, (byte) 21, + (byte) 139, (byte) 152, (byte) 201, (byte) 247, (byte) 164, (byte) 117, (byte) 249, (byte) 79, (byte) 166, + (byte) 41, (byte) 195, (byte) 20, (byte) 132, (byte) 124, (byte) 164, (byte) 85, (byte) 16, (byte) 115, + (byte) 32, (byte) 126, (byte) 240, (byte) 129, (byte) 235, (byte) 82, (byte) 117, (byte) 224, (byte) 83, + (byte) 74, (byte) 226, (byte) 118, (byte) 235, (byte) 212, (byte) 212, (byte) 161, (byte) 79, (byte) 28, + (byte) 243, (byte) 92, (byte) 143, (byte) 115, (byte) 182, (byte) 229, (byte) 121, (byte) 0, (byte) 14, + (byte) 50, (byte) 41, (byte) 207, (byte) 3, (byte) 202, (byte) 192, (byte) 39, (byte) 62, (byte) 167, + (byte) 210, (byte) 174, (byte) 195, (byte) 100, (byte) 101, (byte) 96, (byte) 207, (byte) 144, (byte) 61, + (byte) 43, (byte) 78, (byte) 27, (byte) 116, (byte) 81, (byte) 133, (byte) 0, (byte) 98, (byte) 183, + (byte) 167, (byte) 69, (byte) 189, (byte) 89, (byte) 140, (byte) 235, (byte) 168, (byte) 236, (byte) 83, + (byte) 176, (byte) 177, (byte) 0, (byte) 130, (byte) 252, (byte) 227, (byte) 214, (byte) 180, (byte) 210, + (byte) 60, (byte) 47, (byte) 35, (byte) 156, (byte) 212, (byte) 144, (byte) 198, (byte) 20, (byte) 142, + (byte) 42, (byte) 114, (byte) 163, (byte) 56, (byte) 29, (byte) 235, (byte) 174, (byte) 49, (byte) 81, + (byte) 86, (byte) 71, (byte) 28, (byte) 230, (byte) 228, (byte) 238, (byte) 204, (byte) 125, (byte) 86, + (byte) 216, (byte) 161, (byte) 89, (byte) 194, (byte) 251, (byte) 54, (byte) 59, (byte) 84, (byte) 105, + (byte) 40, (byte) 40, (byte) 174, (byte) 189, (byte) 71, (byte) 167, (byte) 90, (byte) 223, (byte) 186, + (byte) 183, (byte) 89, (byte) 160, (byte) 42, (byte) 195, (byte) 130, (byte) 48, (byte) 107, (byte) 154, + (byte) 8, (byte) 246, (byte) 183, (byte) 13, (byte) 4, (byte) 199, (byte) 31, (byte) 221, (byte) 61, + (byte) 136, (byte) 172, (byte) 106, (byte) 199, (byte) 170, (byte) 58, (byte) 104, (byte) 78, (byte) 234, + (byte) 204, (byte) 149, (byte) 8, (byte) 147, (byte) 118, (byte) 72, (byte) 235, (byte) 154, (byte) 99, + (byte) 40, (byte) 42, (byte) 113, (byte) 131, (byte) 138, (byte) 35, (byte) 27, (byte) 36, (byte) 200, + (byte) 28, (byte) 19, (byte) 79, (byte) 102, (byte) 11, (byte) 209, (byte) 125, (byte) 248, (byte) 172, + (byte) 108, (byte) 117, (byte) 166, (byte) 85, (byte) 224, (byte) 238, (byte) 35, (byte) 29, (byte) 42, + (byte) 1, (byte) 57, (byte) 84, (byte) 62, (byte) 220, (byte) 1, (byte) 235, (byte) 83, (byte) 207, + (byte) 242, (byte) 41, (byte) 218, (byte) 58, (byte) 251, (byte) 209, (byte) 97, (byte) 109, (byte) 188, + (byte) 153, (byte) 88, (byte) 12, (byte) 3, (byte) 133, (byte) 250, (byte) 250, (byte) 213, (byte) 70, + (byte) 23, (byte) 100, (byte) 212, (byte) 154, (byte) 138, (byte) 185, (byte) 3, (byte) 104, (byte) 13, + (byte) 112, (byte) 158, (byte) 107, (byte) 204, (byte) 86, (byte) 86, (byte) 228, (byte) 140, (byte) 112, + (byte) 42, (byte) 75, (byte) 125, (byte) 60, (byte) 89, (byte) 194, (byte) 82, (byte) 89, (byte) 93, + (byte) 73, (byte) 63, (byte) 120, (byte) 30, (byte) 43, (byte) 105, (byte) 27, (byte) 229, (byte) 7, + (byte) 20, (byte) 247, (byte) 69, (byte) 117, (byte) 33, (byte) 128, (byte) 32, (byte) 245, (byte) 205, + (byte) 110, (byte) 233, (byte) 163, (byte) 139, (byte) 219, (byte) 73, (byte) 238, (byte) 103, (byte) 36, + (byte) 42, (byte) 121, (byte) 243, (byte) 73, (byte) 255, (byte) 0, (byte) 129, (byte) 84, (byte) 130, + (byte) 20, (byte) 35, (byte) 33, (byte) 219, (byte) 254, (byte) 250, (byte) 172, (byte) 251, (byte) 203, + (byte) 83, (byte) 167, (byte) 75, (byte) 231, (byte) 196, (byte) 187, (byte) 161, (byte) 39, (byte) 230, + (byte) 83, (byte) 218, (byte) 174, (byte) 91, (byte) 205, (byte) 105, (byte) 60, (byte) 97, (byte) 208, + (byte) 168, (byte) 227, (byte) 167, (byte) 165, (byte) 100, (byte) 213, (byte) 141, (byte) 58, (byte) 93, + (byte) 18, (byte) 249, (byte) 49, (byte) 255, (byte) 0, (byte) 120, (byte) 243, (byte) 254, (byte) 213, + (byte) 30, (byte) 84, (byte) 93, (byte) 50, (byte) 127, (byte) 239, (byte) 170, (byte) 81, (byte) 228, + (byte) 15, (byte) 238, (byte) 81, (byte) 254, (byte) 142, (byte) 23, (byte) 248, (byte) 41, (byte) 8, + (byte) 60, (byte) 168, (byte) 127, (byte) 188, (byte) 127, (byte) 239, (byte) 170, (byte) 41, (byte) 63, + (byte) 209, (byte) 255, (byte) 0, (byte) 216, (byte) 162, (byte) 141, (byte) 7, (byte) 115, (byte) 67, + (byte) 29, (byte) 232, (byte) 199, (byte) 81, (byte) 235, (byte) 79, (byte) 160, (byte) 138, (byte) 163, + (byte) 51, (byte) 152, (byte) 117, (byte) 38, (byte) 233, (byte) 148, (byte) 15, (byte) 226, (byte) 34, + (byte) 180, (byte) 173, (byte) 237, (byte) 48, (byte) 1, (byte) 97, (byte) 255, (byte) 0, (byte) 214, + (byte) 169, (byte) 160, (byte) 176, (byte) 219, (byte) 44, (byte) 147, (byte) 75, (byte) 221, (byte) 142, + (byte) 209, (byte) 87, (byte) 226, (byte) 139, (byte) 208, (byte) 126, (byte) 116, (byte) 233, (byte) 210, + (byte) 183, (byte) 188, (byte) 199, (byte) 86, (byte) 173, (byte) 215, (byte) 42, (byte) 35, (byte) 142, + (byte) 53, (byte) 94, (byte) 49, (byte) 83, (byte) 249, (byte) 67, (byte) 32, (byte) 140, (byte) 84, + (byte) 137, (byte) 22, (byte) 57, (byte) 53, (byte) 32, (byte) 94, (byte) 245, (byte) 185, (byte) 206, + (byte) 49, (byte) 83, (byte) 10, (byte) 24, (byte) 118, (byte) 52, (byte) 253, (byte) 185, (byte) 96, + (byte) 77, (byte) 57, (byte) 70, (byte) 65, (byte) 200, (byte) 169, (byte) 54, (byte) 240, (byte) 41, + (byte) 12, (byte) 16, (byte) 238, (byte) 5, (byte) 79, (byte) 81, (byte) 84, (byte) 53, (byte) 61, + (byte) 60, (byte) 93, (byte) 33, (byte) 3, (byte) 135, (byte) 31, (byte) 116, (byte) 214, (byte) 134, + (byte) 222, (byte) 132, (byte) 83, (byte) 156, (byte) 110, (byte) 92, (byte) 142, (byte) 162, (byte) 144, + (byte) 211, (byte) 105, (byte) 221, (byte) 28, (byte) 121, (byte) 183, (byte) 185, (byte) 137, (byte) 138, + (byte) 156, (byte) 241, (byte) 237, (byte) 71, (byte) 152, (byte) 234, (byte) 62, (byte) 97, (byte) 205, + (byte) 116, (byte) 146, (byte) 91, (byte) 164, (byte) 255, (byte) 0, (byte) 49, (byte) 24, (byte) 35, + (byte) 140, (byte) 138, (byte) 161, (byte) 45, (byte) 178, (byte) 36, (byte) 152, (byte) 35, (byte) 154, + (byte) 194, (byte) 81, (byte) 104, (byte) 236, (byte) 133, (byte) 85, (byte) 35, (byte) 13, (byte) 163, + (byte) 121, (byte) 166, (byte) 85, (byte) 60, (byte) 100, (byte) 214, (byte) 196, (byte) 80, (byte) 4, + (byte) 9, (byte) 26, (byte) 224, (byte) 119, (byte) 168, (byte) 4, (byte) 5, (byte) 175, (byte) 14, + (byte) 209, (byte) 192, (byte) 239, (byte) 90, (byte) 98, (byte) 220, (byte) 44, (byte) 91, (byte) 137, + (byte) 201, (byte) 29, (byte) 42, (byte) 233, (byte) 167, (byte) 185, (byte) 157, (byte) 121, (byte) 105, + (byte) 98, (byte) 154, (byte) 41, (byte) 85, (byte) 83, (byte) 219, (byte) 161, (byte) 169, (byte) 151, + (byte) 142, (byte) 61, (byte) 63, (byte) 149, (byte) 72, (byte) 209, (byte) 0, (byte) 132, (byte) 122, + (byte) 115, (byte) 81, (byte) 99, (byte) 24, (byte) 173, (byte) 142, (byte) 113, (byte) 110, (byte) 33, + (byte) 73, (byte) 237, (byte) 200, (byte) 97, (byte) 199, (byte) 67, (byte) 244, (byte) 174, (byte) 94, + (byte) 214, (byte) 69, (byte) 176, (byte) 212, (byte) 222, (byte) 7, (byte) 251, (byte) 164, (byte) 227, + (byte) 165, (byte) 117, (byte) 145, (byte) 99, (byte) 12, (byte) 167, (byte) 21, (byte) 205, (byte) 248, + (byte) 146, (byte) 31, (byte) 42, (byte) 120, (byte) 231, (byte) 69, (byte) 231, (byte) 161, (byte) 250, + (byte) 138, (byte) 206, (byte) 162, (byte) 208, (byte) 214, (byte) 139, (byte) 215, (byte) 151, (byte) 185, + (byte) 171, (byte) 190, (byte) 35, (byte) 252, (byte) 56, (byte) 252, (byte) 40, (byte) 221, (byte) 22, + (byte) 51, (byte) 183, (byte) 255, (byte) 0, (byte) 29, (byte) 168, (byte) 236, (byte) 174, (byte) 60, + (byte) 251, (byte) 84, (byte) 125, (byte) 135, (byte) 36, (byte) 96, (byte) 212, (byte) 197, (byte) 184, + (byte) 255, (byte) 0, (byte) 86, (byte) 213, (byte) 137, (byte) 67, (byte) 124, (byte) 216, (byte) 191, + (byte) 186, (byte) 127, (byte) 239, (byte) 154, (byte) 41, (byte) 124, (byte) 207, (byte) 250, (byte) 100, + (byte) 223, (byte) 149, (byte) 20, (byte) 12, (byte) 209, (byte) 198, (byte) 120, (byte) 169, (byte) 35, + (byte) 143, (byte) 113, (byte) 246, (byte) 20, (byte) 152, (byte) 61, (byte) 106, (byte) 196, (byte) 73, + (byte) 182, (byte) 44, (byte) 250, (byte) 214, (byte) 145, (byte) 87, (byte) 102, (byte) 82, (byte) 118, + (byte) 34, (byte) 88, (byte) 183, (byte) 201, (byte) 147, (byte) 208, (byte) 118, (byte) 171, (byte) 11, + (byte) 31, (byte) 124, (byte) 83, (byte) 97, (byte) 24, (byte) 82, (byte) 125, (byte) 77, (byte) 90, + (byte) 3, (byte) 3, (byte) 21, (byte) 165, (byte) 204, (byte) 200, (byte) 74, (byte) 99, (byte) 154, + (byte) 66, (byte) 184, (byte) 197, (byte) 78, (byte) 87, (byte) 62, (byte) 244, (byte) 214, (byte) 92, + (byte) 227, (byte) 210, (byte) 139, (byte) 136, (byte) 131, (byte) 163, (byte) 98, (byte) 165, (byte) 2, + (byte) 145, (byte) 151, (byte) 231, (byte) 252, (byte) 42, (byte) 80, (byte) 56, (byte) 161, (byte) 140, + (byte) 140, (byte) 112, (byte) 219, (byte) 79, (byte) 122, (byte) 90, (byte) 71, (byte) 24, (byte) 193, + (byte) 29, (byte) 169, (byte) 123, (byte) 231, (byte) 214, (byte) 129, (byte) 145, (byte) 178, (byte) 158, + (byte) 171, (byte) 138, (byte) 169, (byte) 120, (byte) 141, (byte) 144, (byte) 248, (byte) 233, (byte) 214, + (byte) 175, (byte) 16, (byte) 122, (byte) 83, (byte) 72, (byte) 12, (byte) 118, (byte) 176, (byte) 224, + (byte) 138, (byte) 26, (byte) 186, (byte) 176, (byte) 70, (byte) 78, (byte) 46, (byte) 230, (byte) 84, + (byte) 17, (byte) 147, (byte) 48, (byte) 53, (byte) 121, (byte) 211, (byte) 10, (byte) 5, (byte) 71, + (byte) 111, (byte) 9, (byte) 75, (byte) 135, (byte) 95, (byte) 238, (byte) 244, (byte) 171, (byte) 18, + (byte) 142, (byte) 71, (byte) 214, (byte) 148, (byte) 21, (byte) 145, (byte) 85, (byte) 37, (byte) 205, + (byte) 34, (byte) 177, (byte) 4, (byte) 231, (byte) 138, (byte) 132, (byte) 175, (byte) 31, (byte) 90, + (byte) 182, (byte) 87, (byte) 4, (byte) 212, (byte) 44, (byte) 160, (byte) 49, (byte) 21, (byte) 68, + (byte) 21, (byte) 199, (byte) 202, (byte) 224, (byte) 254, (byte) 117, (byte) 71, (byte) 196, (byte) 16, + (byte) 249, (byte) 154, (byte) 116, (byte) 140, (byte) 163, (byte) 37, (byte) 112, (byte) 195, (byte) 250, + (byte) 214, (byte) 139, (byte) 167, (byte) 28, (byte) 117, (byte) 166, (byte) 74, (byte) 162, (byte) 88, + (byte) 25, (byte) 8, (byte) 206, (byte) 84, (byte) 138, (byte) 77, (byte) 93, (byte) 21, (byte) 23, + (byte) 102, (byte) 153, (byte) 207, (byte) 104, (byte) 55, (byte) 18, (byte) 24, (byte) 90, (byte) 61, + (byte) 160, (byte) 224, (byte) 250, (byte) 214, (byte) 182, (byte) 249, (byte) 127, (byte) 184, (byte) 63, + (byte) 58, (byte) 231, (byte) 52, (byte) 150, (byte) 150, (byte) 45, (byte) 65, (byte) 145, (byte) 72, + (byte) 29, (byte) 143, (byte) 21, (byte) 209, (byte) 126, (byte) 255, (byte) 0, (byte) 213, (byte) 115, + (byte) 88, (byte) 29, (byte) 19, (byte) 90, (byte) 134, (byte) 249, (byte) 255, (byte) 0, (byte) 184, + (byte) 159, (byte) 157, (byte) 20, (byte) 126, (byte) 251, (byte) 213, (byte) 127, (byte) 42, (byte) 40, + (byte) 185, (byte) 54, (byte) 53, (byte) 209, (byte) 114, (byte) 192, (byte) 26, (byte) 179, (byte) 39, + (byte) 220, (byte) 0, (byte) 81, (byte) 69, (byte) 109, (byte) 29, (byte) 140, (byte) 36, (byte) 245, + (byte) 31, (byte) 18, (byte) 141, (byte) 192, (byte) 122, (byte) 10, (byte) 177, (byte) 138, (byte) 40, + (byte) 160, (byte) 66, (byte) 116, (byte) 56, (byte) 161, (byte) 128, (byte) 234, (byte) 40, (byte) 162, + (byte) 129, (byte) 12, (byte) 97, (byte) 215, (byte) 233, (byte) 73, (byte) 25, (byte) 36, (byte) 81, + (byte) 69, (byte) 3, (byte) 7, (byte) 25, (byte) 28, (byte) 83, (byte) 87, (byte) 238, (byte) 224, + (byte) 209, (byte) 69, (byte) 48, (byte) 23, (byte) 60, (byte) 82, (byte) 48, (byte) 252, (byte) 232, + (byte) 162, (byte) 128, (byte) 19, (byte) 0, (byte) 190, (byte) 238, (byte) 132, (byte) 140, (byte) 26, + (byte) 107, (byte) 140, (byte) 156, (byte) 122, (byte) 81, (byte) 69, (byte) 2, (byte) 68, (byte) 108, + (byte) 188, (byte) 212, (byte) 110, (byte) 189, (byte) 40, (byte) 162, (byte) 129, (byte) 145, (byte) 55, + (byte) 99, (byte) 81, (byte) 72, (byte) 187, (byte) 64, (byte) 97, (byte) 235, (byte) 69, (byte) 20, + (byte) 193, (byte) 28, (byte) 124, (byte) 136, (byte) 209, (byte) 235, (byte) 178, (byte) 5, (byte) 114, + (byte) 191, (byte) 188, (byte) 61, (byte) 43, (byte) 162, (byte) 242, (byte) 164, (byte) 219, (byte) 254, + (byte) 185, (byte) 191, (byte) 33, (byte) 69, (byte) 21, (byte) 206, (byte) 247, (byte) 58, (byte) 166, + (byte) 244, (byte) 66, (byte) 249, (byte) 18, (byte) 255, (byte) 0, (byte) 207, (byte) 193, (byte) 255, + (byte) 0, (byte) 190, (byte) 104, (byte) 162, (byte) 138, (byte) 68, (byte) 159, (byte) 255, (byte) 217 + + }; + +} diff --git a/src/net/sourceforge/plantuml/eggs/PSystemRIPFactory.java b/src/net/sourceforge/plantuml/eggs/PSystemRIPFactory.java new file mode 100644 index 000000000..70316c1f9 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/PSystemRIPFactory.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.io.IOException; + +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemRIPFactory implements PSystemBasicFactory { + + private PSystemRIP system; + + public PSystemRIPFactory() { + reset(); + } + + public void reset() { + } + + public boolean executeLine(String line) { + if (line.equalsIgnoreCase("jean canouet")) { + try { + system = new PSystemRIP(); + return true; + } catch (IOException e) { + Log.error("Error " + e); + e.printStackTrace(); + return false; + } + } + return false; + } + + public PSystemRIP getSystem() { + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/SentenceDecoder.java b/src/net/sourceforge/plantuml/eggs/SentenceDecoder.java new file mode 100644 index 000000000..f695f1db4 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/SentenceDecoder.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.io.UnsupportedEncodingException; + +public class SentenceDecoder { + + private final String secret; + + public SentenceDecoder(String sentence1, byte[] crypted) throws UnsupportedEncodingException { + final byte[] key = EggUtils.fromSecretSentence(sentence1).toByteArray(); + final byte[] sen2 = EggUtils.xor(crypted, key); + this.secret = new String(sen2, "UTF-8"); + } + + public boolean isOk() { + for (char c : secret.toCharArray()) { + if ((int) c > 256) { + return false; + } + if (Character.isDefined(c) == false) { + return false; + } + if (Character.isISOControl(c)) { + return false; + } + } + return true; + } + + public String getSecret() { + return secret; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/SentenceProducer.java b/src/net/sourceforge/plantuml/eggs/SentenceProducer.java new file mode 100644 index 000000000..74f889cf6 --- /dev/null +++ b/src/net/sourceforge/plantuml/eggs/SentenceProducer.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.eggs; + +import java.io.UnsupportedEncodingException; + +public class SentenceProducer { + + private final String secret; + + public SentenceProducer(String sentence1, String sentence2) throws UnsupportedEncodingException { + final byte[] key = EggUtils.fromSecretSentence(sentence1).toByteArray(); + final byte[] sen2 = sentence2.getBytes("UTF-8"); + final byte[] crypted = EggUtils.xor(sen2, key); + this.secret = EggUtils.fromByteArrays(crypted); + } + + public String getSecret() { + return secret; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/AbstractInkscape.java b/src/net/sourceforge/plantuml/eps/AbstractInkscape.java new file mode 100644 index 000000000..6b00bdd7a --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/AbstractInkscape.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.io.File; +import java.io.IOException; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.dot.ProcessRunner; + +abstract class AbstractInkscape implements Inkscape { + + abstract protected File specificExe(); + + AbstractInkscape() { + throw new UnsupportedOperationException("Not used anymore"); + } + + final public void createEps(File svg, File eps) throws IOException, InterruptedException { + final StringBuilder cmd = new StringBuilder(); + appendFilePath(cmd, searchDotExe()); + cmd.append(" -E "); + appendFilePath(cmd, eps); + cmd.append(" "); + appendFilePath(cmd, svg); + eps.delete(); + if (eps.exists()) { + throw new IOException("Cannot delete " + eps); + } + String result = executeCmd(cmd.toString()); + if (eps.exists() == false) { + throw new IOException("File not created " + eps); + } + } + + private File searchDotExe() { + final String getenv = InkscapeUtils.getenvInkscape(); + if (getenv == null) { + return specificExe(); + } + return new File(getenv); + } + + abstract protected void appendFilePath(final StringBuilder sb, File file); + + private String executeCmd(final String cmd) throws IOException, InterruptedException { + final ProcessRunner p = new ProcessRunner(cmd); + p.run(null, null); + final StringBuilder sb = new StringBuilder(); + if (StringUtils.isNotEmpty(p.getOut())) { + sb.append(p.getOut()); + } + if (StringUtils.isNotEmpty(p.getError())) { + if (sb.length() > 0) { + sb.append(' '); + } + sb.append(p.getError()); + } + return sb.toString().replace('\n', ' ').trim(); + } + +} diff --git a/src/net/sourceforge/plantuml/eps/EpsGraphics.java b/src/net/sourceforge/plantuml/eps/EpsGraphics.java new file mode 100644 index 000000000..3ccefaf77 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/EpsGraphics.java @@ -0,0 +1,456 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.awt.Color; +import java.awt.geom.PathIterator; +import java.awt.image.BufferedImage; +import java.util.Date; +import java.util.Locale; + +import net.sourceforge.plantuml.ugraphic.UGradient; + +public class EpsGraphics { + + // http://www.linuxfocus.org/Francais/May1998/article43.html + // http://www.tailrecursive.org/postscript/text.html + private final StringBuilder body = new StringBuilder(); + private final StringBuilder header = new StringBuilder(); + + private Color color = Color.BLACK; + private Color fillcolor = Color.BLACK; + + private String strokeWidth = "1"; + private String strokeDasharray = null; + + private final PostScriptCommandMacro setcolorgradient = new PostScriptCommandMacro("setcolorgradient"); + private final PostScriptCommandMacro simplerect = new PostScriptCommandMacro("simplerect"); + private final PostScriptCommandMacro roundrect = new PostScriptCommandMacro("roundrect"); + private boolean setcolorgradientUsed = false; + private boolean simplerectUsed = false; + private boolean roundrectUsed = false; + + public EpsGraphics() { + header.append("%!PS-Adobe-3.0 EPSF-3.0\n"); + header.append("%%Creator: PlantUML\n"); + header.append("%%Title: noTitle\n"); + header.append("%%CreationDate: " + new Date() + "\n"); + setcolorgradient.add(new PostScriptCommandRaw("3 index 7 index sub 1 index mul 7 index add")); + setcolorgradient.add(new PostScriptCommandRaw("3 index 7 index sub 2 index mul 7 index add")); + setcolorgradient.add(new PostScriptCommandRaw("3 index 7 index sub 3 index mul 7 index add")); + setcolorgradient.add(new PostScriptCommandRaw("setrgbcolor")); + // setcolorgradient.add(new PostScriptCommandRaw("0 7 1 {pop} for")); + setcolorgradient.add(new PostScriptCommandRaw("pop pop pop pop pop pop pop ")); + + simplerect.add(new PostScriptCommandRaw("newpath moveto 1 index 0 rlineto")); + simplerect.add(new PostScriptCommandRaw("0 exch rlineto")); + simplerect.add(new PostScriptCommandRaw("neg 0 rlineto")); + + roundrect.add(new PostScriptCommandRaw("newpath")); + roundrect.add(new PostScriptCommandRaw("dup 3 index add 2 index 2 index add 2 index 180 270 arc")); + roundrect + .add(new PostScriptCommandRaw("2 index 5 index add 1 index sub 2 index 2 index add 2 index 270 0 arc")); + roundrect.add(new PostScriptCommandRaw( + "2 index 5 index add 1 index sub 2 index 5 index add 2 index sub 2 index 0 90 arc")); + roundrect.add(new PostScriptCommandRaw("dup 3 index add 2 index 5 index add 2 index sub 2 index 90 180 arc")); + roundrect.add(new PostScriptCommandRaw("pop pop pop pop pop ")); + } + + private boolean closeDone = false; + + private int maxX = 10; + private int maxY = 10; + + final protected void ensureVisible(double x, double y) { + if (x > maxX) { + maxX = (int) (x + 1); + } + if (y > maxY) { + maxY = (int) (y + 1); + } + } + + protected final Color getColor() { + return color; + } + + public void close() { + checkCloseDone(); + + header.append("%%BoundingBox: 0 0 " + maxX + " " + maxY + "\n"); + // header.append("%%DocumentData: Clean7Bit\n"); + // header.append("%%DocumentProcessColors: Black\n"); + header.append("%%ColorUsage: Color\n"); + header.append("%%Origin: 0 0\n"); + header.append("%%EndComments\n\n"); + header.append("gsave\n"); + header.append("0 " + maxY + " translate\n"); + header.append("1 -1 scale\n"); + if (setcolorgradientUsed) { + header.append(setcolorgradient.getPostStringDefinition()); + } + if (simplerectUsed) { + header.append(simplerect.getPostStringDefinition()); + } + if (roundrectUsed) { + header.append(roundrect.getPostStringDefinition()); + } + + append("grestore"); + + // if(isClipSet()) + // writer.write("grestore\n"); + + append("showpage"); + append("%%EOF"); + closeDone = true; + } + + private void checkCloseDone() { + if (closeDone) { + throw new IllegalStateException(); + } + } + + public String getEPSCode() { + if (closeDone == false) { + close(); + } + return header.toString() + getBodyString(); + } + + protected String getBodyString() { + return body.toString(); + } + + public final void setStrokeColor(Color c) { + checkCloseDone(); + this.color = c; + } + + public void setFillColor(Color c) { + checkCloseDone(); + this.fillcolor = c; + } + + public final void setStrokeWidth(String strokeWidth, String strokeDasharray) { + checkCloseDone(); + this.strokeWidth = strokeWidth; + this.strokeDasharray = strokeDasharray; + } + + public void epsLine(double x1, double y1, double x2, double y2) { + ensureVisible(x1, y1); + ensureVisible(x2, y2); + if (strokeDasharray != null) { + append("[" + strokeDasharray + "] 0 setdash"); + } + checkCloseDone(); + append(strokeWidth + " setlinewidth"); + appendColor(color); + append("newpath"); + append(format(x1) + " " + format(y1) + " moveto"); + append(format(x2 - x1) + " " + format(y2 - y1) + " rlineto"); + append("closepath stroke"); + ensureVisible(Math.max(x1, x2), Math.max(y1, y2)); + if (strokeDasharray != null) { + append("[] 0 setdash"); + } + } + + public void epsPolygon(double... points) { + checkCloseDone(); + double lastX = 0; + double lastY = 0; + if (fillcolor != null) { + appendColor(fillcolor); + append("newpath"); + for (int i = 0; i < points.length; i += 2) { + ensureVisible(points[i], points[i + 1]); + if (i == 0) { + append(format(points[i]) + " " + format(points[i + 1]) + " moveto"); + } else { + append(format(points[i] - lastX) + " " + format(points[i + 1] - lastY) + " rlineto"); + } + lastX = points[i]; + lastY = points[i + 1]; + } + append(format(points[0]) + " " + format(points[1]) + " lineto"); + append("closepath eofill"); + } + + if (color != null) { + append(strokeWidth + " setlinewidth"); + appendColor(color); + append("newpath"); + for (int i = 0; i < points.length; i += 2) { + ensureVisible(points[i], points[i + 1]); + if (i == 0) { + append(format(points[i]) + " " + format(points[i + 1]) + " moveto"); + } else { + append(format(points[i] - lastX) + " " + format(points[i + 1] - lastY) + " rlineto"); + } + lastX = points[i]; + lastY = points[i + 1]; + } + append(format(points[0]) + " " + format(points[1]) + " lineto"); + append("closepath stroke"); + } + + } + + public void epsRectangle(double x, double y, double width, double height, double rx, double ry) { + checkCloseDone(); + ensureVisible(x, y); + ensureVisible(x + width, y + height); + if (fillcolor != null) { + appendColor(fillcolor); + epsRectangleInternal(x, y, width, height, rx, ry); + append("closepath eofill"); + } + + if (color != null) { + append(strokeWidth + " setlinewidth"); + appendColor(color); + epsRectangleInternal(x, y, width, height, rx, ry); + append("closepath stroke"); + } + } + + public void epsRectangle(double x, double y, double width, double height, double rx, double ry, UGradient gr) { + checkCloseDone(); + ensureVisible(x, y); + ensureVisible(x + width, y + height); + setcolorgradientUsed = true; + + if (rx == 0 && ry == 0) { + simplerectUsed = true; + appendColorShort(gr.getColor1()); + appendColorShort(gr.getColor2()); + append(format(width) + " " + format(height) + " " + format(x) + " " + format(y)); + append("100 -1 1 {"); + append("100 div"); + append("newpath"); + append("2 index 2 index moveto"); + append("dup 5 index mul 2 mul dup 0 rlineto"); + append("neg 4 index 2 index mul 2 mul rlineto"); + append("closepath eoclip"); + append("10 index 10 index 10 index"); + append("10 index 10 index 10 index"); + append("6 index setcolorgradient"); + append("4 index 4 index 4 index 4 index simplerect"); + append("closepath eofill"); + append("pop"); + append("} for"); + append("pop pop pop pop"); + append("pop pop pop"); + append("pop pop pop"); + append("initclip"); + } else { + roundrectUsed = true; + appendColorShort(gr.getColor1()); + appendColorShort(gr.getColor2()); + append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " " + + format((rx + ry) / 2)); + append("100 -1 1 {"); + append("100 div"); + append("newpath"); + append("3 index 3 index moveto"); + append("dup 6 index mul 2 mul dup 0 rlineto"); + append("neg 5 index 2 index mul 2 mul rlineto"); + append("closepath eoclip"); + append("11 index 11 index 11 index"); + append("11 index 11 index 11 index"); + append("6 index setcolorgradient"); + append("5 index 5 index 5 index 5 index 5 index roundrect"); + append("closepath eofill"); + append("pop"); + append("} for"); + append("pop pop pop pop pop"); + append("pop pop pop"); + append("pop pop pop"); + append("initclip"); + } + } + + private void epsRectangleInternal(double x, double y, double width, double height, double rx, double ry) { + if (rx == 0 && ry == 0) { + simpleRectangle(x, y, width, height); + } else { + roundRectangle(x, y, width, height, rx, ry); + } + } + + private void roundRectangle(double x, double y, double width, double height, double rx, double ry) { + append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " " + format((rx + ry) / 2) + + " roundrect"); + roundrectUsed = true; + } + + private void simpleRectangle(double x, double y, double width, double height) { + append(format(width) + " " + format(height) + " " + format(x) + " " + format(y) + " simplerect"); + simplerectUsed = true; + } + + public void epsEllipse(double x, double y, double xRadius, double yRadius) { + checkCloseDone(); + ensureVisible(x + xRadius, y + yRadius); + if (xRadius != yRadius) { + throw new UnsupportedOperationException(); + } + if (fillcolor != null) { + appendColor(fillcolor); + append("newpath"); + append(format(x) + " " + format(y) + " " + format(xRadius) + " 0 360 arc"); + append("closepath eofill"); + } + + if (color != null) { + append(strokeWidth + " setlinewidth"); + appendColor(color); + append("newpath"); + append(format(x) + " " + format(y) + " " + format(xRadius) + " 0 360 arc"); + append("closepath stroke"); + } + } + + protected void appendColor(Color c) { + final double r = c.getRed() / 255.0; + final double g = c.getGreen() / 255.0; + final double b = c.getBlue() / 255.0; + append(format(r) + " " + format(g) + " " + format(b) + " setrgbcolor"); + } + + protected void appendColorShort(Color c) { + final double r = c.getRed() / 255.0; + final double g = c.getGreen() / 255.0; + final double b = c.getBlue() / 255.0; + append(format(r) + " " + format(g) + " " + format(b)); + } + + public static String format(double x) { + if (x == 0) { + return "0"; + } + String s = String.format(Locale.US, "%1.4f", x); + s = s.replaceAll("(\\.\\d*?)0+$", "$1"); + if (s.endsWith(".")) { + s = s.substring(0, s.length() - 1); + } + return s; + } + + protected void append(String s) { + if (s.indexOf(" ") != -1) { + throw new IllegalArgumentException(s); + } + body.append(s + "\n"); + } + + // FONT + public void moveto(double x1, double y1) { + append(format(x1) + " " + format(y1) + " moveto"); + ensureVisible(x1, y1); + } + + public void lineto(double x1, double y1) { + append(format(x1) + " " + format(y1) + " lineto"); + ensureVisible(x1, y1); + } + + public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) { + append(format(x1) + " " + format(y1) + " " + format(x2) + " " + format(y2) + " " + format(x3) + " " + + format(y3) + " curveto"); + ensureVisible(x1, y1); + ensureVisible(x2, y2); + ensureVisible(x3, y3); + } + + public void quadto(double x1, double y1, double x2, double y2) { + append(format(x1) + " " + format(y1) + " " + format(x1) + " " + format(y1) + " " + format(x2) + " " + + format(y2) + " curveto"); + ensureVisible(x1, y1); + ensureVisible(x2, y2); + } + + public void newpath() { + append("0 setlinewidth"); + append("[] 0 setdash"); + appendColor(color); + append("newpath"); + } + + public void closepath() { + append("closepath"); + } + + public void fill(int windingRule) { + append("%fill"); + if (windingRule == PathIterator.WIND_EVEN_ODD) { + append("eofill"); + } else if (windingRule == PathIterator.WIND_NON_ZERO) { + append("fill"); + } + } + + public void drawImage(BufferedImage image, double x, double y) { + final int width = image.getWidth(); + final int height = image.getHeight(); + append("gsave"); + append(format(x) + " " + format(y) + " translate"); + append(format(width) + " " + format(height) + " scale"); + append("" + width + " " + height + " 8 [" + width + " 0 0 -" + height + " 0 " + height + "]"); + // append("" + width + " " + height + " 8 [0 0 0 0 0 0]"); + append("{<"); + final StringBuilder sb = new StringBuilder(); + for (int j = height - 1; j >= 0; j--) { + for (int i = 0; i < width; i++) { + final String hexString = getRgb(image.getRGB(i, j)); + assert hexString.length() == 6; + sb.append(hexString); + } + } + append(sb.toString()); + // append(">} image"); + append(">} false 3 colorimage"); + ensureVisible(x + width, y + height); + append("grestore"); + } + + static String getRgb(int x) { + final String s = "000000" + Integer.toHexString(x); + return s.substring(s.length() - 6); + } + +} diff --git a/src/net/sourceforge/plantuml/eps/EpsGraphicsMacro.java b/src/net/sourceforge/plantuml/eps/EpsGraphicsMacro.java new file mode 100644 index 000000000..734163d65 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/EpsGraphicsMacro.java @@ -0,0 +1,166 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.awt.geom.PathIterator; +import java.util.HashMap; +import java.util.Map; + +public class EpsGraphicsMacro extends EpsGraphics { + + private final PostScriptData data = new PostScriptData(); + private final PostScriptCommandMacro rquadto = new PostScriptCommandMacro("rquadto"); + + public EpsGraphicsMacro() { + super(); + rquadto.add(new PostScriptCommandRaw("3 index 3 index 4 2 roll rcurveto")); + } + + @Override + protected void append(String s) { + if (s.indexOf(" ") != -1) { + throw new IllegalArgumentException(s); + } + data.add(new PostScriptCommandRaw(s)); + } + + @Override + protected String getBodyString() { + final StringBuilder sb = new StringBuilder(); + sb.append(rquadto.getPostStringDefinition()); + for (PostScriptCommandMacro macro : macros.keySet()) { + sb.append(macro.getPostStringDefinition()); + } + sb.append(data.toPostString()); + return sb.toString(); + } + + // FONT + private double posX; + private double posY; + private int macroCpt; + private final Map macros = new HashMap(); + + @Override + public void newpath() { + append("0 setlinewidth"); + append("[] 0 setdash"); + appendColor(getColor()); + append("newpath"); + } + + @Override + public void closepath() { + macroInProgress.add(new PostScriptCommandRaw("closepath")); + closeMacro(); + } + + @Override + public void fill(int windingRule) { + if (windingRule == PathIterator.WIND_EVEN_ODD) { + append("eofill"); + } else if (windingRule == PathIterator.WIND_NON_ZERO) { + append("fill"); + } + } + + private PostScriptCommandMacro macroInProgress = null; + + @Override + public void moveto(double x1, double y1) { + data.add(new PostScriptCommandMoveTo(x1, y1)); + this.posX = x1; + this.posY = y1; + openMacro(); + ensureVisible(x1, y1); + } + + @Override + public void lineto(double x1, double y1) { + final PostScriptCommand cmd = new PostScriptCommandLineTo(x1 - posX, y1 - posY); + macroInProgress.add(cmd); + this.posX = x1; + this.posY = y1; + ensureVisible(x1, y1); + } + + @Override + public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) { + final PostScriptCommandCurveTo cmd = new PostScriptCommandCurveTo(x1 - posX, y1 - posY, x2 - posX, y2 - posY, + x3 - posX, y3 - posY); + macroInProgress.add(cmd); + this.posX = x3; + this.posY = y3; + ensureVisible(x1, y1); + ensureVisible(x2, y2); + ensureVisible(x3, y3); + } + + @Override + public void quadto(double x1, double y1, double x2, double y2) { + final PostScriptCommandQuadTo cmd = new PostScriptCommandQuadTo(x1 - posX, y1 - posY, x2 - posX, y2 - posY); + macroInProgress.add(cmd); + this.posX = x2; + this.posY = y2; + ensureVisible(x1, y1); + ensureVisible(x2, y2); + } + + private void openMacro() { + if (macroInProgress != null) { + throw new IllegalStateException(); + } + macroInProgress = new PostScriptCommandMacro(macroName()); + } + + private String macroName() { + return "P$" + Integer.toString(macroCpt, 36); + } + + private void closeMacro() { + if (macroInProgress == null) { + throw new IllegalStateException(); + } + final String existingName = macros.get(macroInProgress); + if (existingName == null) { + macros.put(macroInProgress, macroInProgress.getName()); + append(macroName()); + macroCpt++; + } else { + append(existingName); + } + macroInProgress = null; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/EpsStrategy.java b/src/net/sourceforge/plantuml/eps/EpsStrategy.java new file mode 100644 index 000000000..c2be93028 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/EpsStrategy.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public enum EpsStrategy { + + VERY_SIMPLE, WITH_MACRO; + + public EpsGraphics creatEpsGraphics() { + if (this == VERY_SIMPLE) { + return new EpsGraphics(); + } + if (this == WITH_MACRO) { + return new EpsGraphicsMacro(); + } + throw new IllegalArgumentException(); + } + + public static EpsStrategy getDefault() { + return WITH_MACRO; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/Inkscape.java b/src/net/sourceforge/plantuml/eps/Inkscape.java new file mode 100644 index 000000000..9ea14b9c9 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/Inkscape.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.io.File; +import java.io.IOException; + +public interface Inkscape { + + public void createEps(File svg, File eps) throws IOException, InterruptedException; +} diff --git a/src/net/sourceforge/plantuml/eps/InkscapeLinux.java b/src/net/sourceforge/plantuml/eps/InkscapeLinux.java new file mode 100644 index 000000000..5d89f975e --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/InkscapeLinux.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.io.File; + +class InkscapeLinux extends AbstractInkscape { + + @Override + protected File specificExe() { + final File usrLocalBin = new File("/usr/local/bin/inkscape"); + if (usrLocalBin.exists()) { + return usrLocalBin; + } + + final File usrBin = new File("/usr/bin/inkscape"); + if (usrBin.exists()) { + return usrBin; + } + return null; + } + + @Override + protected void appendFilePath(final StringBuilder sb, File file) { + sb.append(file.getAbsolutePath()); + } + +} diff --git a/src/net/sourceforge/plantuml/eps/InkscapeUtils.java b/src/net/sourceforge/plantuml/eps/InkscapeUtils.java new file mode 100644 index 000000000..b38bd3f2c --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/InkscapeUtils.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.io.File; + +public class InkscapeUtils { + + private static boolean isWindows() { + return File.separatorChar == '\\'; + } + + public static Inkscape create() { + if (isWindows()) { + return new InkscapeWindows(); + } + return new InkscapeLinux(); + } + + public static String getenvInkscape() { + final String env = System.getProperty("INKSCAPE"); + if (env != null) { + return env; + } + return System.getenv("INKSCAPE"); + } + +} diff --git a/src/net/sourceforge/plantuml/eps/InkscapeWindows.java b/src/net/sourceforge/plantuml/eps/InkscapeWindows.java new file mode 100644 index 000000000..9a68cd51d --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/InkscapeWindows.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4826 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.io.File; + +class InkscapeWindows extends AbstractInkscape { + + @Override + protected File specificExe() { + final File f1 = new File("C:\\Program Files\\Inkscape\\inkscape.exe"); + if (f1.exists()) { + return f1; + } + + final File f2 = new File("C:\\Program Files (x86)\\Inkscape\\inkscape.exe"); + if (f2.exists()) { + return f2; + } + + return null; + } + + @Override + protected void appendFilePath(final StringBuilder sb, File file) { + sb.append('\"'); + sb.append(file.getAbsolutePath()); + sb.append('\"'); + } + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommand.java b/src/net/sourceforge/plantuml/eps/PostScriptCommand.java new file mode 100644 index 000000000..aa937d3bf --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommand.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public interface PostScriptCommand { + + String toPostString(); + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommandCurveTo.java b/src/net/sourceforge/plantuml/eps/PostScriptCommandCurveTo.java new file mode 100644 index 000000000..8a6447dba --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommandCurveTo.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public class PostScriptCommandCurveTo implements PostScriptCommand { + + private final double x1; + private final double y1; + private final double x2; + private final double y2; + private final double x3; + private final double y3; + + public PostScriptCommandCurveTo(double x1, double y1, double x2, double y2, double x3, double y3) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + this.x3 = x3; + this.y3 = y3; + } + + public String toPostString() { + return EpsGraphics.format(x1) + " " + EpsGraphics.format(y1) + " " + EpsGraphics.format(x2) + " " + + EpsGraphics.format(y2) + " " + EpsGraphics.format(x3) + " " + EpsGraphics.format(y3) + " rcurveto"; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommandLineTo.java b/src/net/sourceforge/plantuml/eps/PostScriptCommandLineTo.java new file mode 100644 index 000000000..d240f150c --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommandLineTo.java @@ -0,0 +1,51 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + + +public class PostScriptCommandLineTo implements PostScriptCommand { + + private final double x; + private final double y; + + public PostScriptCommandLineTo(double x, double y) { + this.x = x; + this.y = y; + } + + public String toPostString() { + return EpsGraphics.format(x) + " " + EpsGraphics.format(y) + " rlineto"; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommandMacro.java b/src/net/sourceforge/plantuml/eps/PostScriptCommandMacro.java new file mode 100644 index 000000000..2bb932925 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommandMacro.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public class PostScriptCommandMacro implements PostScriptCommand { + + final private String name; + final private PostScriptData data = new PostScriptData(); + + public PostScriptCommandMacro(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void add(PostScriptCommand cmd) { + data.add(cmd); + } + + public String toPostString() { + return name; + } + + public String getPostStringDefinition() { + final StringBuilder sb = new StringBuilder(); + sb.append("/" + name + " {\n"); + sb.append(data.toPostString()); + sb.append("} def\n"); + return sb.toString(); + } + + @Override + public int hashCode() { + return data.toPostString().hashCode(); + } + + @Override + public boolean equals(Object obj) { + final PostScriptCommandMacro other = (PostScriptCommandMacro) obj; + return this.data.toPostString().equals(other.data.toPostString()); + } + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommandMoveTo.java b/src/net/sourceforge/plantuml/eps/PostScriptCommandMoveTo.java new file mode 100644 index 000000000..b84e39153 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommandMoveTo.java @@ -0,0 +1,49 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public class PostScriptCommandMoveTo implements PostScriptCommand { + + private final double x; + private final double y; + + public PostScriptCommandMoveTo(double x, double y) { + this.x = x; + this.y = y; + } + + public String toPostString() { + return EpsGraphics.format(x) + " " + EpsGraphics.format(y) + " moveto"; + } +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommandQuadTo.java b/src/net/sourceforge/plantuml/eps/PostScriptCommandQuadTo.java new file mode 100644 index 000000000..db65eb43b --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommandQuadTo.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public class PostScriptCommandQuadTo implements PostScriptCommand { + + private final double x1; + private final double y1; + private final double x2; + private final double y2; + + public PostScriptCommandQuadTo(double x1, double y1, double x2, double y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + } + + public String toPostString() { + return EpsGraphics.format(x1) + " " + EpsGraphics.format(y1) + " " + EpsGraphics.format(x2) + " " + + EpsGraphics.format(y2) + " rquadto"; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptCommandRaw.java b/src/net/sourceforge/plantuml/eps/PostScriptCommandRaw.java new file mode 100644 index 000000000..1220ea206 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptCommandRaw.java @@ -0,0 +1,51 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +public class PostScriptCommandRaw implements PostScriptCommand { + + final private String cmd; + + public PostScriptCommandRaw(String cmd) { + if (cmd.indexOf('\n') != -1) { + throw new IllegalArgumentException(cmd); + } + this.cmd = cmd; + } + + public String toPostString() { + return cmd; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/PostScriptData.java b/src/net/sourceforge/plantuml/eps/PostScriptData.java new file mode 100644 index 000000000..6f6226477 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/PostScriptData.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.util.ArrayList; +import java.util.List; + +public class PostScriptData { + + private final List data = new ArrayList(); + + private String toString; + + public String toPostString() { + if (this.toString == null) { + this.toString = toPostStringSlow(); + } + return this.toString; + } + + private String toPostStringSlow() { + final StringBuilder sb = new StringBuilder(); + for (PostScriptCommand cmd : data) { + sb.append(cmd.toPostString()); + sb.append('\n'); + } + return sb.toString(); + } + + public void add(PostScriptCommand cmd) { + data.add(cmd); + this.toString = null; + } + +} diff --git a/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java b/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java new file mode 100644 index 000000000..0cf595844 --- /dev/null +++ b/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java @@ -0,0 +1,89 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4207 $ + * + */ +package net.sourceforge.plantuml.eps; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; + +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMaker; + +public class SvgToEpsConverter { + + private final Inkscape inkscape; + private final File svgFile; + + public SvgToEpsConverter(String svg) throws IOException { + if (svg == null) { + throw new IllegalArgumentException(); + } + this.inkscape = InkscapeUtils.create(); + this.svgFile = CucaDiagramFileMaker.createTempFile("convert", ".svg"); + final PrintWriter pw = new PrintWriter(svgFile); + pw.println(svg); + pw.close(); + } + + public SvgToEpsConverter(File svgFile) { + if (svgFile == null) { + throw new IllegalArgumentException(); + } + this.inkscape = InkscapeUtils.create(); + this.svgFile = svgFile; + } + + public void createEps(File epsFile) throws IOException, InterruptedException { + inkscape.createEps(svgFile, epsFile); + } + + + public void createEps(OutputStream os) throws IOException, InterruptedException { + final File epsFile = CucaDiagramFileMaker.createTempFile("eps", ".eps"); + createEps(epsFile); + int read; + final InputStream is = new FileInputStream(epsFile); + while ((read = is.read()) != -1) { + os.write(read); + } + is.close(); + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + epsFile.delete(); + } + } + +} diff --git a/src/net/sourceforge/plantuml/geom/AbstractFigure.java b/src/net/sourceforge/plantuml/geom/AbstractFigure.java new file mode 100644 index 000000000..6f75eba05 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/AbstractFigure.java @@ -0,0 +1,311 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +abstract class AbstractFigure { + + private final Set segments = new HashSet(); + + @Override + public String toString() { + return segments.toString(); + } + + @Override + final public boolean equals(Object obj) { + final AbstractFigure other = (AbstractFigure) obj; + return segments.equals(other.segments); + } + + @Override + final public int hashCode() { + return segments.hashCode(); + } + + protected boolean knowThisPoint(Point2DInt p) { + for (LineSegmentInt seg : segments) { + if (seg.getP1().equals(p) || seg.getP2().equals(p)) { + return true; + } + } + return false; + } + + LineSegmentInt existingSegment(Point2DInt p1, Point2DInt p2) { + for (LineSegmentInt seg : segments) { + if (seg.getP1().equals(p1) && seg.getP2().equals(p2)) { + return seg; + } + if (seg.getP1().equals(p2) && seg.getP2().equals(p1)) { + return seg; + } + } + return null; + } + + Collection getSegmentsWithExtremity(Point2DInt extremity, Collection exceptions) { + final Collection result = new HashSet(); + for (LineSegmentInt seg : segments) { + if (exceptions.contains(seg)) { + continue; + } + if (seg.getP1().equals(extremity) || seg.getP2().equals(extremity)) { + result.add(seg); + } + } + return Collections.unmodifiableCollection(result); + } + + void addSegment(LineSegmentInt seg) { + segments.add(seg); + } + + protected final Set getSegments() { + return Collections.unmodifiableSet(segments); + } + + @Deprecated + public Polyline addPath(Point2DInt start, Point2DInt end) { + if (knowThisPoint(start) && knowThisPoint(end)) { + return getPath(start, end); + } + final LineSegmentInt direct = new LineSegmentInt(start, end); + addSegment(direct); + return new PolylineImpl(start, end); + } + + public Polyline addDirectLink(Point2DInt start, Point2DInt end) { + final LineSegmentInt direct = new LineSegmentInt(start, end); + addSegment(direct); + System.err.println("AbstractFigure::addDirectLink " + direct); + return new PolylineImpl(start, end); + } + + public boolean isSimpleSegmentPossible(Point2DInt start, Point2DInt end) { + final LineSegmentInt direct = new LineSegmentInt(start, end); + return hasIntersectionStrict(direct) == false; + } + + public Polyline getPath(Pointable start, Pointable end) { + if (knowThisPoint(start.getPosition()) == false) { + throw new IllegalArgumentException(); + } + if (knowThisPoint(end.getPosition()) == false) { + throw new IllegalArgumentException("" + end.getPosition()); + } + if (isSimpleSegmentPossible(start.getPosition(), end.getPosition())) { + throw new IllegalArgumentException(); + // return new PolylineImpl(start, end); + } + if (arePointsConnectable(start.getPosition(), end.getPosition()) == false) { + return null; + } + return findBestPath(start, end); + } + + private Polyline findBestPath(Pointable start, Pointable end) { + System.err.println("start=" + start.getPosition()); + System.err.println("end=" + end.getPosition()); + final Set points = getAllPoints(); + if (points.contains(start.getPosition()) == false || points.contains(end.getPosition()) == false) { + throw new IllegalArgumentException(); + } + points.remove(start.getPosition()); + points.remove(end.getPosition()); + final List neighborhoods = new ArrayList(); + for (Point2DInt p : points) { + neighborhoods.addAll(getSingularity(p).getNeighborhoods()); + } + for (int i = 0; i < neighborhoods.size(); i++) { + System.err.println("N" + (i + 1) + " " + neighborhoods.get(i)); + } + final Dijkstra dijkstra = new Dijkstra(neighborhoods.size() + 2); + System.err.println("size=" + dijkstra.getSize()); + for (int i = 0; i < neighborhoods.size(); i++) { + if (isConnectable(start.getPosition(), neighborhoods.get(i))) { + dijkstra.addLink(0, i + 1, distance(start.getPosition(), neighborhoods.get(i).getCenter())); + } + } + for (int i = 0; i < neighborhoods.size(); i++) { + for (int j = 0; j < neighborhoods.size(); j++) { + if (i == j) { + continue; + } + if (isConnectable(neighborhoods.get(i), neighborhoods.get(j))) { + dijkstra.addLink(i + 1, j + 1, distance(neighborhoods.get(i).getCenter(), neighborhoods.get(j) + .getCenter())); + } + } + } + for (int i = 0; i < neighborhoods.size(); i++) { + if (isConnectable(end.getPosition(), neighborhoods.get(i))) { + dijkstra.addLink(i + 1, neighborhoods.size() + 1, distance(end.getPosition(), neighborhoods.get(i) + .getCenter())); + } + } + final List path = dijkstra.getBestPath(); + if (path.get(path.size() - 1) != neighborhoods.size() + 1) { + throw new IllegalStateException("No Path"); + } + assert path.size() > 2; + + System.err.println("PATH=" + path); + final List usedNeighborhoods = new ArrayList(); + for (int i = 1; i < path.size() - 1; i++) { + final int idx = path.get(i) - 1; + usedNeighborhoods.add(neighborhoods.get(idx)); + } + return findApproximatePath(start, end, usedNeighborhoods); + } + + private Polyline findApproximatePath(Pointable start, Pointable end, final List neighborhoods) { + System.err + .println("findApproximatePath " + start.getPosition() + " " + end.getPosition() + " " + neighborhoods); + final PolylineImpl result = new PolylineImpl(start, end); + for (Neighborhood n : neighborhoods) { + System.err.println("Neighborhood =" + n); + final double d = getProximaDistance(n.getCenter()) / 2; + final double a = n.getMiddle(); + System.err.println("d=" + d); + System.err.println("a=" + a * 180 / Math.PI); + final double deltaX = d * Math.cos(a); + final double deltaY = d * Math.sin(a); + assert d > 0; + System.err.println("Result = " + n.getCenter().translate((int) deltaX, (int) deltaY)); + result.addIntermediate(n.getCenter().translate((int) deltaX, (int) deltaY)); + } + return result; + } + + private double getProximaDistance(Point2DInt center) { + double result = Double.MAX_VALUE; + for (Point2DInt p : getAllPoints()) { + if (center.equals(p)) { + continue; + } + final double cur = new LineSegmentInt(p, center).getLength(); + result = Math.min(result, cur); + } + return result; + } + + static private double distance(Point2DInt p1, Point2DInt p2) { + return new LineSegmentInt(p1, p2).getLength(); + } + + boolean isConnectable(Point2DInt p, Neighborhood n) { + final LineSegmentInt seg = new LineSegmentInt(n.getCenter(), p); + if (hasIntersectionStrict(seg)) { + return false; + } + final double angle = Singularity.convertAngle(seg.getAngle()); + return n.isInAngleLarge(angle); + } + + boolean isConnectable(Neighborhood n1, Neighborhood n2) { + final boolean result = isConnectableInternal(n1, n2); + assert result == isConnectableInternal(n2, n1); + return result; + } + + private boolean isConnectableInternal(Neighborhood n1, Neighborhood n2) { + if (n1.getCenter().equals(n2.getCenter())) { + return false; + } + final LineSegmentInt seg1 = new LineSegmentInt(n1.getCenter(), n2.getCenter()); + if (hasIntersectionStrict(seg1)) { + return false; + } + final double angle1 = Singularity.convertAngle(seg1.getAngle()); + final double angle2 = Singularity.convertAngle(seg1.getOppositeAngle()); + assert angle2 == Singularity.convertAngle(new LineSegmentInt(n2.getCenter(), n1.getCenter()).getAngle()); + if (n1.isInAngleStrict(angle1) && n2.isInAngleStrict(angle2)) { + return true; + } + if (n1.isAngleLimit(angle1) && n2.isAngleLimit(angle2)) { + if (n1.is360() || n2.is360()) { + return true; + } + final Orientation o1 = n1.getOrientationFrom(angle1); + final Orientation o2 = n2.getOrientationFrom(angle2); + return o1 != o2; + } + return false; + } + + private boolean hasIntersectionStrict(LineSegmentInt direct) { + for (LineSegmentInt seg : getSegments()) { + if (seg.atLeastOneCommonExtremities(direct)) { + continue; + } + if (seg.doesIntersect(direct)) { + System.err.println("seg=" + seg); + System.err.println("direct=" + direct); + System.err.println("AbstractFigure::hasIntersectionStrict true"); + return true; + } + } + System.err.println("AbstractFigure::hasIntersectionStrict false"); + return false; + } + + Singularity getSingularity(Point2DInt center) { + final Singularity singularity = new Singularity(center); + for (LineSegmentInt seg : getSegments()) { + if (seg.containsPoint(center)) { + singularity.addLineSegment(seg); + } + } + return singularity; + } + + private Set getAllPoints() { + final Set result = new HashSet(); + for (LineSegmentInt seg : segments) { + result.add(seg.getP1()); + result.add(seg.getP2()); + } + return result; + } + + abstract boolean arePointsConnectable(Point2DInt p1, Point2DInt p2); + +} diff --git a/src/net/sourceforge/plantuml/geom/AbstractLineSegment.java b/src/net/sourceforge/plantuml/geom/AbstractLineSegment.java new file mode 100644 index 000000000..8886bd65f --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/AbstractLineSegment.java @@ -0,0 +1,254 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +public abstract class AbstractLineSegment extends Line2D { + + @Override + final public boolean equals(Object obj) { + final AbstractLineSegment other = (AbstractLineSegment) obj; + return this.getP1().equals(other.getP1()) && getP2().equals(other.getP2()); + } + + @Override + final public int hashCode() { + int result = 7; + final int multiplier = 17; + result = result * multiplier + getP1().hashCode(); + result = result * multiplier + getP2().hashCode(); + return result; + } + + final public double getLength() { + return Math.sqrt((getP2().getX() - getP1().getX()) * (getP2().getX() - getP1().getX()) + + (getP2().getY() - getP1().getY()) * (getP2().getY() - getP1().getY())); + } + + final protected Point2D.Double getPoint2D(double u) { + final double x = getP1().getX() + u * (getP2().getX() - getP1().getX()); + final double y = getP1().getY() + u * (getP2().getY() - getP1().getY()); + return new Point2D.Double(x, y); + } + + final public double getDistance(Point2D f) { + return this.ptSegDist(f); + } + + public Point2D getSegIntersection(AbstractLineSegment other) { + final double u; + if (other.isVertical()) { + u = getIntersectionVertical(other.getP1().getX()); + } else if (other.isHorizontal()) { + u = getIntersectionHorizontal(other.getP1().getY()); + } else { + throw new UnsupportedOperationException(); + } + if (java.lang.Double.isNaN(u) || u < 0 || u > 1) { + return null; + } + final Point2D.Double result = getPoint2D(u); + if (isBetween(result, other.getP1(), other.getP2())) { + return result; + } + return null; + } + + private static boolean isBetween(double value, double v1, double v2) { + if (v1 < v2) { + return value >= v1 && value <= v2; + } + assert v2 <= v1; + return value >= v2 && value <= v1; + + } + + static boolean isBetween(Point2D toTest, Point2D pos1, Point2D pos2) { + return isBetween(toTest.getX(), pos1.getX(), pos2.getX()) && isBetween(toTest.getY(), pos1.getY(), pos2.getY()); + } + + private double getIntersectionVertical(double xOther) { + final double coef = getP2().getX() - getP1().getX(); + if (coef == 0) { + return java.lang.Double.NaN; + } + return (xOther - getP1().getX()) / coef; + } + + private double getIntersectionHorizontal(double yOther) { + final double coef = getP2().getY() - getP1().getY(); + if (coef == 0) { + return java.lang.Double.NaN; + } + return (yOther - getP1().getY()) / coef; + } + + // Line2D + + @Override + final public void setLine(double x1, double y1, double x2, double y2) { + throw new UnsupportedOperationException(); + } + + final public Rectangle2D getBounds2D() { + final double x; + final double w; + if (getX1() < getX2()) { + x = getX1(); + w = getX2() - getX1(); + } else { + x = getX2(); + w = getX1() - getX2(); + } + final double y; + final double h; + if (getY1() < getY2()) { + y = getY1(); + h = getY2() - getY1(); + } else { + y = getY2(); + h = getY1() - getY2(); + } + return new Rectangle2D.Double(x, y, w, h); + } + + final public boolean isHorizontal() { + return getP1().getY() == getP2().getY(); + } + + final public boolean isVertical() { + return getP1().getX() == getP2().getX(); + } + + final public double getDistance(AbstractLineSegment other) { + final double result = getDistanceInternal(other); + assert equals(result, other.getDistanceInternal(this)); + return result; + } + + private boolean equals(double a1, double a2) { + return Math.abs(a1 - a2) < 0.0001; + } + + private double getDistanceInternal(AbstractLineSegment other) { + double result = this.getDistance(other.getP1()); + result += this.getDistance(other.getP2()); + result += other.getDistance(this.getP1()); + result += other.getDistance(this.getP2()); + return result; + } + + final public double getAngle() { + return Math.atan2(getP2().getY() - getP1().getY(), getP2().getX() - getP1().getX()); + } + + final public double getOppositeAngle() { + return Math.atan2(getP1().getY() - getP2().getY(), getP1().getX() - getP2().getX()); + } + + final public Point2D.Double startTranslatedAsVector(double u) { + final double pour = 1.0 * u / 100.0; + final double x = getP1().getX() + pour * (getP2().getX() - getP1().getX()); + final double y = getP1().getY() + pour * (getP2().getY() - getP1().getY()); + return new Point2D.Double(x, y); + } + + public boolean doesIntersect(AbstractLineSegment other) { + final boolean result = doesIntersectInternal(other); + assert result == other.doesIntersectInternal(this); + return result; + } + + private boolean doesIntersectInternal(AbstractLineSegment other) { + final double d1 = direction(other.getP1(), other.getP2(), this.getP1()); + final double d2 = direction(other.getP1(), other.getP2(), this.getP2()); + final double d3 = direction(this.getP1(), this.getP2(), other.getP1()); + final double d4 = direction(this.getP1(), this.getP2(), other.getP2()); + + if (d1 == 0 && isBetween(this.getP1(), other.getP1(), other.getP2())) { + return true; + } + + if (d2 == 0 && isBetween(this.getP2(), other.getP1(), other.getP2())) { + return true; + } + + if (d3 == 0 && isBetween(other.getP1(), this.getP1(), this.getP2())) { + return true; + } + + if (d4 == 0 && isBetween(other.getP2(), this.getP1(), this.getP2())) { + return true; + } + + final boolean result = signDiffers(d1, d2) && signDiffers(d3, d4); + assert this.intersectsLine(other) == result; + return result; + } + + private static double direction(Point2D origin, Point2D point1, Point2D point2) { + return determinant(point2.getX() - origin.getX(), point2.getY() - origin.getY(), point1.getX() - origin.getX(), + point1.getY() - origin.getY()); + } + + private static boolean signDiffers(double a, double b) { + if (a > 0 && b < 0) { + return true; + } + if (a < 0 && b > 0) { + return true; + } + return false; + } + + public double determinant(AbstractLineSegment other) { + return determinant(this.getP1().getX() - this.getP2().getX(), this.getP1().getY() - this.getP2().getY(), other + .getP1().getX() + - other.getP2().getX(), other.getP1().getY() - other.getP2().getY()); + } + + private static double determinant(double x1, double y1, double x2, double y2) { + return x1 * y2 - x2 * y1; + } + + public double side(Point2D point) { + // assert Math.signum(direction(p1, p2, point)) == + // this.relativeCCW(point); + return direction(getP1(), getP2(), point); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/AbstractPolyline.java b/src/net/sourceforge/plantuml/geom/AbstractPolyline.java new file mode 100644 index 000000000..5b0994b96 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/AbstractPolyline.java @@ -0,0 +1,198 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.awt.geom.GeneralPath; + +abstract class AbstractPolyline implements Polyline { + + private final Pointable start; + private final Pointable end; + + public AbstractPolyline(Pointable start, Pointable end) { + this.start = start; + this.end = end; + } + + @Override + final public String toString() { + return segments().toString(); + } + + final public boolean doesTouch(Polyline other) { + final boolean result = doesTouchInternal(other); + assert result == ((AbstractPolyline) other).doesTouchInternal(this); + return result; + } + + private boolean doesTouchInternal(Polyline other) { + for (int i = 0; i < nbSegments(); i++) { + final LineSegmentInt seg1 = segments().get(i); + for (int j = 0; j < other.nbSegments(); j++) { + final LineSegmentInt seg2 = other.segments().get(j); + final boolean ignoreExtremities = i == 0 || i == nbSegments() - 1 || j == 0 + || j == other.nbSegments() - 1; + if (ignoreExtremities == false && seg1.doesIntersect(seg2)) { + return true; + } + if (ignoreExtremities && seg1.doesIntersectButNotSameExtremity(seg2)) { + return true; + } + } + } + return false; + } + + final public LineSegmentInt getFirst() { + return segments().get(0); + } + + final public LineSegmentInt getLast() { + return segments().get(nbSegments() - 1); + } + + final public double getLength() { + double result = 0; + for (LineSegmentInt seg : segments()) { + result += seg.getLength(); + } + return result; + } + + final public Point2DInt clipStart(Box box) { + assert box.doesIntersect(segments().get(0)); + final Point2DInt inter[] = box.intersect(segments().get(0)); + assert inter.length == 1; + segments().set( + 0, + new LineSegmentInt(inter[0].getXint(), inter[0].getYint(), segments().get(0).getP2().getXint(), + segments().get(0).getP2().getYint())); + return inter[0]; + } + + final public Point2DInt clipEnd(Box box) { + final int last = nbSegments() - 1; + if (last == -1) { + return null; + } + assert box.doesIntersect(segments().get(last)); + final Point2DInt inter[] = box.intersect(segments().get(last)); + assert inter.length == 1; + segments().set( + last, + new LineSegmentInt(segments().get(last).getP1().getXint(), segments().get(last).getP1().getYint(), + inter[0].getXint(), inter[0].getYint())); + return inter[0]; + } + + final public boolean intersectBox(Box b) { + for (LineSegmentInt seg : segments()) { + if (b.doesIntersect(seg)) { + return true; + } + } + return false; + } + + final public double getDistance(Box b) { + double result = Double.MAX_VALUE; + for (LineSegmentInt seg : segments()) { + if (b.doesIntersect(seg)) { + result = Math.min(result, seg.getDistance(b.getCenterPoint())); + } + } + return result; + } + + final public double getDistance(Polyline other) { + double result = 0; + for (LineSegmentInt seg1 : segments()) { + for (LineSegmentInt seg2 : other.segments()) { + result += seg1.getDistance(seg2); + } + } + return result; + } + + final public GeneralPath asGeneralPath() { + final GeneralPath generalPath = new GeneralPath(); + + for (LineSegmentInt seg : segments()) { + generalPath.append(seg, false); + } + + return generalPath; + } + + final public int getMinX() { + int result = Integer.MAX_VALUE; + for (LineSegmentInt seg : segments()) { + result = Math.min(result, seg.getMinX()); + } + return result; + } + + final public int getMinY() { + int result = Integer.MAX_VALUE; + for (LineSegmentInt seg : segments()) { + result = Math.min(result, seg.getMinY()); + } + return result; + } + + final public int getMaxX() { + int result = Integer.MIN_VALUE; + for (LineSegmentInt seg : segments()) { + result = Math.max(result, seg.getMaxX()); + } + return result; + } + + final public int getMaxY() { + int result = Integer.MIN_VALUE; + for (LineSegmentInt seg : segments()) { + result = Math.max(result, seg.getMaxY()); + } + return result; + } + + public final Pointable getStart() { + return start; + } + + public final Pointable getEnd() { + return end; + } + +} diff --git a/src/net/sourceforge/plantuml/geom/Box.java b/src/net/sourceforge/plantuml/geom/Box.java new file mode 100644 index 000000000..932cc407a --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Box.java @@ -0,0 +1,238 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +public class Box implements XMoveable, Pointable { + + private int x; + private int y; + final private int width; + final private int height; + + public Box(int x, int y, int width, int height) { + if (width <= 0 || height <= 0) { + throw new IllegalArgumentException(); + } + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + @Override + public String toString() { + return "Box [" + x + "," + y + "] " + width + "," + height; + } + + public Point2DInt[] getCorners() { + final Point2DInt p1 = new Point2DInt(getX(), getY()); + final Point2DInt p2 = new Point2DInt(getX() + getWidth(), getY()); + final Point2DInt p3 = new Point2DInt(getX() + getWidth(), getY() + getHeight()); + final Point2DInt p4 = new Point2DInt(getX(), getY() + getHeight()); + return new Point2DInt[] { p1, p2, p3, p4 }; + } + + public Point2DInt[] getCornersOfOneSide(LineSegmentInt seg, int sgn) { + final Point2DInt[] corners = getCorners(); + final double sgn0 = seg.side(corners[0]); + final double sgn1 = seg.side(corners[1]); + final double sgn2 = seg.side(corners[2]); + final double sgn3 = seg.side(corners[3]); + int nb = 0; + if (Math.signum(sgn0) == sgn) { + nb++; + } + if (Math.signum(sgn1) == sgn) { + nb++; + } + if (Math.signum(sgn2) == sgn) { + nb++; + } + if (Math.signum(sgn3) == sgn) { + nb++; + } + final Point2DInt[] result = new Point2DInt[nb]; + int i = 0; + if (Math.signum(sgn0) == sgn) { + result[i++] = corners[0]; + } + if (Math.signum(sgn1) == sgn) { + result[i++] = corners[1]; + } + if (Math.signum(sgn2) == sgn) { + result[i++] = corners[2]; + } + if (Math.signum(sgn3) == sgn) { + result[i++] = corners[3]; + } + assert nb == i; + return result; + } + + public boolean doesIntersect(LineSegmentInt seg) { + return intersect(seg).length > 0; + } + + public Point2DInt[] intersect(LineSegmentInt seg) { + if (seg.side(this) != 0) { + return new Point2DInt[0]; + } + // System.err.println("THIS=" + this); + // System.err.println("LineSegment=" + seg); + final Point2DInt corners[] = getCorners(); + final LineSegmentInt seg1 = new LineSegmentInt(corners[0], corners[1]); + final LineSegmentInt seg2 = new LineSegmentInt(corners[1], corners[2]); + final LineSegmentInt seg3 = new LineSegmentInt(corners[2], corners[3]); + final LineSegmentInt seg4 = new LineSegmentInt(corners[3], corners[0]); + final Point2DInt i1 = seg.getSegIntersection(seg1); + Point2DInt i2 = seg.getSegIntersection(seg2); + Point2DInt i3 = seg.getSegIntersection(seg3); + Point2DInt i4 = seg.getSegIntersection(seg4); + + // System.err.println("i1="+i1); + // System.err.println("i2="+i2); + // System.err.println("i3="+i3); + // System.err.println("i4="+i4); + + if (i2 != null && i2.equals(i1)) { + i2 = null; + } + if (i3 != null && (i3.equals(i1) || i3.equals(i2))) { + i3 = null; + } + if (i4 != null && (i4.equals(i1) || i4.equals(i2) || i4.equals(i3))) { + i4 = null; + } + + final int nb = countNotNull(i1, i2, i3, i4); + assert nb >= 0 && nb <= 3 : nb; + int i = 0; + final Point2DInt result[] = new Point2DInt[nb]; + if (i1 != null) { + result[i++] = i1; + } + if (i2 != null) { + result[i++] = i2; + } + if (i3 != null) { + result[i++] = i3; + } + if (i4 != null) { + result[i++] = i4; + } + assert i == nb; + assert getCornersOfOneSide(seg, 0).length + getCornersOfOneSide(seg, 1).length + + getCornersOfOneSide(seg, -1).length == 4; + return result; + } + + private int countNotNull(Point2DInt i1, Point2DInt i2, Point2DInt i3, Point2DInt i4) { + int n = 0; + if (i1 != null) { + n++; + } + if (i2 != null) { + n++; + } + if (i3 != null) { + n++; + } + if (i4 != null) { + n++; + } + return n; + } + + public Box outerBox(int margin) { + return new Box(x - margin, y - margin, width + 2 * margin, height + 2 * margin); + } + + public Point2DInt getCenterPoint() { + return new Point2DInt(x + width / 2, y + height / 2); + } + + public void moveX(int delta) { + this.x += delta; + } + + public boolean intersectBox(Box other) { + return other.x + other.width > this.x && other.y + other.height > this.y && other.x < this.x + this.width + && other.y < this.y + this.height; + } + + public final int getX() { + return x; + } + + public final int getY() { + return y; + } + + public final int getWidth() { + return width; + } + + public final int getHeight() { + return height; + } + + public int getMinX() { + return x; + } + + public int getMinY() { + return y; + } + + public int getMaxX() { + return x + width; + } + + public int getMaxY() { + return y + height; + } + + public int getCenterX() { + return x + width / 2; + } + + public int getCenterY() { + return y + height / 2; + } + + public Point2DInt getPosition() { + return getCenterPoint(); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/ClosedArea.java b/src/net/sourceforge/plantuml/geom/ClosedArea.java new file mode 100644 index 000000000..b54004153 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/ClosedArea.java @@ -0,0 +1,295 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +public class ClosedArea extends AbstractFigure { + + private final List points = new ArrayList(); + private final List segmentsList = new ArrayList(); + + private int minY = Integer.MAX_VALUE; + private int minX = Integer.MAX_VALUE; + private int maxX = Integer.MIN_VALUE; + private int maxY = Integer.MIN_VALUE; + + public ClosedArea() { + assert isConsistent(); + } + + @Override + public String toString() { + return points.toString(); + } + + public boolean contains(Point2DInt point) { + return contains(point.getXint(), point.getYint()); + } + + private boolean contains(int x, int y) { + if (points.size() <= 2) { + return false; + } + if (x > maxX) { + return false; + } + if (x < minX) { + return false; + } + if (y > maxY) { + return false; + } + if (y < minY) { + return false; + } + if (isOnFrontier(new Point2DInt(x, y))) { + return true; + } + int hits = 0; + + int lastx = getLastPoint().getXint(); + int lasty = getLastPoint().getYint(); + int curx; + int cury; + + // Walk the edges of the polygon + for (int i = 0; i < points.size(); lastx = curx, lasty = cury, i++) { + curx = points.get(i).getXint(); + cury = points.get(i).getYint(); + + if (cury == lasty) { + continue; + } + + final int leftx; + if (curx < lastx) { + if (x >= lastx) { + continue; + } + leftx = curx; + } else { + if (x >= curx) { + continue; + } + leftx = lastx; + } + + final double test1; + final double test2; + if (cury < lasty) { + if (y < cury || y >= lasty) { + continue; + } + if (x < leftx) { + hits++; + continue; + } + test1 = x - curx; + test2 = y - cury; + } else { + if (y < lasty || y >= cury) { + continue; + } + if (x < leftx) { + hits++; + continue; + } + test1 = x - lastx; + test2 = y - lasty; + } + + if (test1 < test2 / (lasty - cury) * (lastx - curx)) { + hits++; + } + + } + return (hits & 1) != 0; + + } + + private boolean isConsistent() { + assert getSegments().size() == segmentsList.size(); + assert getSegments().equals(new HashSet(segmentsList)); + if (getSegments().size() > 0) { + assert getSegments().size() + 1 == points.size() : "points=" + points + " getSegment()=" + getSegments(); + } + for (int i = 0; i < segmentsList.size(); i++) { + final LineSegmentInt seg = segmentsList.get(i); + if (seg.sameExtremities(new LineSegmentInt(points.get(i), points.get(i + 1))) == false) { + return false; + } + } + return true; + } + + public boolean isOnFrontier(Point2DInt point) { + for (LineSegmentInt seg : segmentsList) { + if (seg.containsPoint(point)) { + return true; + } + } + return false; + } + + public boolean isClosed() { + if (getSegments().size() < 3) { + return false; + } + if (getFirstSegment().atLeastOneCommonExtremities(getLastSegment())) { + return true; + } + return false; + } + + ClosedArea append(LineSegmentInt other) { + if (isClosed()) { + throw new IllegalStateException(); + } + if (getSegments().contains(other)) { + throw new IllegalArgumentException(); + } + final ClosedArea result = new ClosedArea(); + for (LineSegmentInt seg : segmentsList) { + result.addSegment(seg); + } + if (result.getSegments().size() > 0 && result.getLastSegment().atLeastOneCommonExtremities(other) == false) { + throw new IllegalArgumentException(); + } + if (points.contains(other.getP1()) && points.contains(other.getP2()) + && other.getP1().equals(getFirstPoint()) == false && other.getP2().equals(getFirstPoint()) == false) { + return null; + } + result.addSegment(other); + assert result.isConsistent(); + + return result; + } + + @Override + protected void addSegment(LineSegmentInt seg) { + super.addSegment(seg); + minY = Math.min(minY, seg.getMinY()); + maxY = Math.max(maxY, seg.getMaxY()); + minX = Math.min(minX, seg.getMinX()); + maxX = Math.max(maxX, seg.getMaxX()); + segmentsList.add(seg); + if (points.size() == 0) { + assert getSegments().size() == 1; + points.add(seg.getP1()); + points.add(seg.getP2()); + } else if (points.size() == 2) { + assert segmentsList.size() == 2; + final LineSegmentInt seg0 = segmentsList.get(0); + final LineSegmentInt seg1 = segmentsList.get(1); + points.clear(); + final Point2DInt common = seg0.getCommonExtremities(seg1); + if (common == null) { + throw new IllegalArgumentException(); + } + assert common.equals(seg1.getCommonExtremities(seg0)); + points.add(seg0.getOtherExtremity(common)); + points.add(common); + points.add(seg1.getOtherExtremity(common)); + + } else { + final Point2DInt lastPoint = getLastPoint(); + points.add(seg.getOtherExtremity(lastPoint)); + } + assert isConsistent(); + } + + private Point2DInt getLastPoint() { + return points.get(points.size() - 1); + } + + private Point2DInt getFirstPoint() { + return points.get(0); + } + + public LineSegmentInt getLastSegment() { + return segmentsList.get(segmentsList.size() - 1); + } + + private LineSegmentInt getFirstSegment() { + return segmentsList.get(0); + } + + public Point2DInt getFreePoint() { + if (isClosed()) { + throw new IllegalStateException(); + } + return getLastPoint(); + } + + public int getMinY() { + return minY; + } + + public int getMinX() { + return minX; + } + + public int getMaxY() { + return maxY; + } + + public int getMaxX() { + return maxX; + } + + public boolean contains(ClosedArea other) { + if (isClosed() == false) { + throw new IllegalStateException(); + } + for (Point2DInt point : other.points) { + if (this.contains(point) == false) { + return false; + } + } + return true; + } + + @Override + boolean arePointsConnectable(Point2DInt p1, Point2DInt p2) { + if (isOnFrontier(p1) || isOnFrontier(p2)) { + return true; + } + final boolean pos1 = contains(p1); + final boolean pos2 = contains(p2); + return pos1 == pos2; + } +} diff --git a/src/net/sourceforge/plantuml/geom/CollectionUtils.java b/src/net/sourceforge/plantuml/geom/CollectionUtils.java new file mode 100644 index 000000000..f5e266d67 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/CollectionUtils.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class CollectionUtils { + + public static Collection> selectUpTo(List original, int nb) { + final List> result = new ArrayList>(); + for (int i = 1; i <= nb; i++) { + result.addAll(selectExactly(original, i)); + } + return Collections.unmodifiableList(result); + } + + public static Collection> selectExactly(List original, int nb) { + if (nb < 0) { + throw new IllegalArgumentException(); + } + if (nb == 0) { + return Collections.emptyList(); + } + if (nb == 1) { + final List> result = new ArrayList>(); + for (E element : original) { + result.add(Collections.singletonList(element)); + } + return result; + + } + if (nb > original.size()) { + return Collections.emptyList(); + } + if (nb == original.size()) { + return Collections.singletonList(original); + } + final List> result = new ArrayList>(); + + for (List subList : selectExactly(original.subList(1, original.size()), nb - 1)) { + final List newList = new ArrayList(); + newList.add(original.get(0)); + newList.addAll(subList); + result.add(Collections.unmodifiableList(newList)); + } + result.addAll(selectExactly(original.subList(1, original.size()), nb)); + + return Collections.unmodifiableList(result); + } +} diff --git a/src/net/sourceforge/plantuml/geom/Dijkstra.java b/src/net/sourceforge/plantuml/geom/Dijkstra.java new file mode 100644 index 000000000..0ff33c2f3 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Dijkstra.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Dijkstra { + + final private double basic[][]; + final private double dist[]; + final private int previous[]; + final private Set q = new HashSet(); + final private int size; + + public Dijkstra(int size) { + this.size = size; + this.basic = new double[size][size]; + this.dist = new double[size]; + this.previous = new int[size]; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + this.basic[i][j] = i == j ? 0 : Double.MAX_VALUE; + } + } + } + + public void addLink(int n1, int n2, double d) { + System.err.println("Adding " + n1 + " " + n2 + " " + d); + if (n1 == n2) { + throw new IllegalArgumentException(); + } + basic[n1][n2] = d; + basic[n2][n1] = d; + + } + + private void init() { + for (int i = 0; i < size; i++) { + this.dist[i] = Double.MAX_VALUE; + this.previous[i] = -1; + this.q.add(i); + } + this.dist[0] = 0; + } + + private void computePrevious() { + init(); + while (q.size() > 0) { + final int u = smallest(); + if (dist[u] == Double.MAX_VALUE) { + return; + } + q.remove(u); + for (int v = 0; v < size; v++) { + if (basic[u][v] == Double.MAX_VALUE) { + continue; + } + final double alt = dist[u] + basic[u][v]; + if (alt < dist[v]) { + dist[v] = alt; + previous[v] = u; + } + } + } + } + + public List getBestPath() { + final List result = new ArrayList(); + computePrevious(); + int u = size - 1; + while (previous[u] >= 0) { + result.add(0, u); + u = previous[u]; + } + result.add(0, 0); + return Collections.unmodifiableList(result); + } + + private int smallest() { + int result = -1; + for (Integer i : q) { + if (result == -1 || dist[i] < dist[result]) { + result = i; + } + } + return result; + } + + public final int getSize() { + return size; + } + +} diff --git a/src/net/sourceforge/plantuml/geom/InflateData.java b/src/net/sourceforge/plantuml/geom/InflateData.java new file mode 100644 index 000000000..872fa207e --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/InflateData.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +public class InflateData implements Comparable { + + private final int pos; + private final int inflation; + + public InflateData(int pos, int inflation) { + if (inflation % 2 != 0) { + throw new IllegalArgumentException(); + } + this.pos = pos; + this.inflation = inflation; + } + + public final int getPos() { + return pos; + } + + public final int getInflation() { + return inflation; + } + + public int compareTo(InflateData other) { + return -(this.pos - other.pos); + } + + @Override + public String toString() { + return "" + pos + " (" + inflation + ")"; + } +} diff --git a/src/net/sourceforge/plantuml/geom/InflationTransform.java b/src/net/sourceforge/plantuml/geom/InflationTransform.java new file mode 100644 index 000000000..39a359757 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/InflationTransform.java @@ -0,0 +1,209 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; +import java.util.SortedSet; +import java.util.TreeSet; + +class Point2DIntComparatorDistance implements Comparator { + + private final Point2DInt center; + + public Point2DIntComparatorDistance(Point2DInt center) { + this.center = center; + } + + public int compare(Point2DInt p1, Point2DInt p2) { + return (int) Math.signum(p1.distance(center) - p2.distance(center)); + } + +} + +public class InflationTransform { + + private final List inflateX = new ArrayList(); + private final List inflateY = new ArrayList(); + + public void addInflationX(int xpos, int inflation) { + add(inflateX, xpos, inflation); + } + + @Override + public String toString() { + return "inflateX = " + inflateX + " inflateY = " + inflateY; + } + + public void addInflationY(int ypos, int inflation) { + add(inflateY, ypos, inflation); + } + + static private void add(List list, int ypos, int inflation) { + for (final ListIterator it = list.listIterator(); it.hasNext();) { + final InflateData cur = it.next(); + if (cur.getPos() == ypos) { + it.set(new InflateData(ypos, Math.max(inflation, cur.getInflation()))); + return; + } + } + list.add(new InflateData(ypos, inflation)); + Collections.sort(list); + } + + Collection cutPoints(LineSegmentInt original) { + + // System.err.println("original=" + original); + // System.err.println("inflateX=" + inflateX); + // System.err.println("inflateY=" + inflateY); + + final SortedSet result = new TreeSet(new Point2DIntComparatorDistance(original.getP1())); + + if (original.isHorizontal() == false) { + for (InflateData x : inflateX) { + final LineSegmentInt vertical = new LineSegmentInt(x.getPos(), original.getMinY(), x.getPos(), original + .getMaxY()); + final Point2DInt inter = original.getSegIntersection(vertical); + if (inter != null) { + result.add(inter); + } + } + } + if (original.isVertical() == false) { + for (InflateData y : inflateY) { + final LineSegmentInt horizontal = new LineSegmentInt(original.getMinX(), y.getPos(), + original.getMaxX(), y.getPos()); + final Point2DInt inter = original.getSegIntersection(horizontal); + if (inter != null) { + result.add(inter); + } + } + } + return result; + } + + Collection cutSegments(LineSegmentInt original) { + final List result = new ArrayList(); + Point2DInt cur = original.getP1(); + final Collection cutPoints = cutPoints(original); + for (Point2DInt inter : cutPoints) { + if (cur.equals(inter)) { + continue; + } + result.add(new LineSegmentInt(cur, inter)); + cur = inter; + } + if (cur.equals(original.getP2()) == false) { + result.add(new LineSegmentInt(cur, original.getP2())); + } + return result; + } + + Collection cutSegments(Collection segments) { + final List result = new ArrayList(); + for (LineSegmentInt seg : segments) { + result.addAll(cutSegments(seg)); + } + return result; + } + + private LineSegmentInt inflateSegment(LineSegmentInt seg) { + if (isOnGrid(seg.getP1()) || isOnGrid(seg.getP2())) { + return new LineSegmentInt(inflatePoint2DInt(seg.getP1()), inflatePoint2DInt(seg.getP2())); + } + for (InflateData x : inflateX) { + seg = seg.inflateXAlpha(x); + } + for (InflateData y : inflateY) { + seg = seg.inflateYAlpha(y); + } + return seg; + } + + private boolean isOnGrid(Point2DInt point) { + boolean onGrid = false; + for (InflateData x : inflateX) { + if (point.getX() == x.getPos()) { + onGrid = true; + } + } + if (onGrid == false) { + return false; + } + for (InflateData y : inflateY) { + if (point.getY() == y.getPos()) { + return true; + } + } + return false; + + } + + public Point2DInt inflatePoint2DInt(Point2DInt point) { + for (InflateData x : inflateX) { + point = point.inflateX(x); + } + for (InflateData y : inflateY) { + point = point.inflateY(y); + } + return point; + } + + List inflateSegmentCollection(Collection segments) { + final List result = new ArrayList(); + for (LineSegmentInt seg : segments) { + result.add(inflateSegment(seg)); + } + return result; + } + + public List inflate(Collection segments) { + final List result = new ArrayList(); + LineSegmentInt last = null; + final Collection cutSegments = cutSegments(segments); + for (LineSegmentInt seg : inflateSegmentCollection(cutSegments)) { + if (last != null && last.getP2().equals(seg.getP1()) == false) { + result.add(new LineSegmentInt(last.getP2(), seg.getP1())); + } + result.add(seg); + last = seg; + + } + return result; + } +} diff --git a/src/net/sourceforge/plantuml/geom/Kingdom.java b/src/net/sourceforge/plantuml/geom/Kingdom.java new file mode 100644 index 000000000..99bbf11cc --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Kingdom.java @@ -0,0 +1,121 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class Kingdom extends AbstractFigure { + + private Set buildClosedArea(ClosedArea area) { + if (area.isClosed()) { + throw new IllegalArgumentException(); + } + final Set result = new HashSet(); + for (LineSegmentInt seg : getSegmentsWithExtremity(area.getFreePoint(), area.getSegments())) { + final ClosedArea newArea = area.append(seg); + if (newArea != null) { + result.add(newArea); + } + } + return Collections.unmodifiableSet(result); + } + + private void grow(Set areas) { + for (ClosedArea area : new HashSet(areas)) { + if (area.isClosed() == false) { + areas.addAll(buildClosedArea(area)); + } + } + } + + Set getAllClosedArea() { + final Set result = new HashSet(); + for (LineSegmentInt seg : getSegments()) { + result.add(new ClosedArea().append(seg)); + } + int lastSize; + do { + lastSize = result.size(); + grow(result); + } while (result.size() != lastSize); + for (final Iterator it = result.iterator(); it.hasNext();) { + final ClosedArea area = it.next(); + if (area.isClosed() == false) { + it.remove(); + } + } + return Collections.unmodifiableSet(result); + } + + // public Set getAllSmallClosedArea() { + // final Set all = getAllClosedArea(); + // final Set result = new HashSet(all); + // + // for (final Iterator it = result.iterator(); it.hasNext();) { + // final ClosedArea area = it.next(); + // if (containsAnotherArea(area, all)) { + // it.remove(); + // } + // } + // + // return Collections.unmodifiableSet(result); + // } + + // static private boolean containsAnotherArea(ClosedArea area, + // Set all) { + // for (ClosedArea another : all) { + // if (another == area) { + // continue; + // } + // if (area.contains(another)) { + // return true; + // } + // } + // return false; + // } + + @Override + boolean arePointsConnectable(Point2DInt p1, Point2DInt p2) { + for (ClosedArea area : getAllClosedArea()) { + if (area.arePointsConnectable(p1, p2) == false) { + return false; + } + } + return true; + } + +} diff --git a/src/net/sourceforge/plantuml/geom/LineSegmentDouble.java b/src/net/sourceforge/plantuml/geom/LineSegmentDouble.java new file mode 100644 index 000000000..830fb67d4 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/LineSegmentDouble.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.awt.geom.Point2D; +import java.util.Locale; + +public class LineSegmentDouble extends AbstractLineSegment { + + private final Point2D p1; + private final Point2D p2; + + @Override + public String toString() { + return String.format(Locale.US, "( %d,%d - %d,%d )", getP1().getX(), getP1().getY(), getP2().getX(), getP2() + .getY()); + } + + public LineSegmentDouble(double x1, double y1, double x2, double y2) { + this(new Point2D.Double(x1, y1), new Point2D.Double(x2, y2)); + } + + public LineSegmentDouble(Point2D p1, Point2D p2) { + this.p1 = p1; + this.p2 = p2; + if (p1.equals(p2)) { + throw new IllegalArgumentException(); + } + assert p1 != null && p2 != null; + assert getLength() > 0; + assert this.getDistance(this) == 0; + } + + @Override + public Point2D getP1() { + return p1; + } + + @Override + public Point2D getP2() { + return p2; + } + + @Override + public double getX1() { + return p1.getX(); + } + + @Override + public double getX2() { + return p2.getX(); + } + + @Override + public double getY1() { + return p1.getY(); + } + + @Override + public double getY2() { + return p2.getY(); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/LineSegmentInt.java b/src/net/sourceforge/plantuml/geom/LineSegmentInt.java new file mode 100644 index 000000000..67d541dda --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/LineSegmentInt.java @@ -0,0 +1,266 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.awt.geom.Point2D; +import java.util.Locale; + +public class LineSegmentInt extends AbstractLineSegment { + + private final Point2DInt p1; + private final Point2DInt p2; + + @Override + public String toString() { + return String.format(Locale.US, "( %d,%d - %d,%d )", p1.getXint(), p1.getYint(), p2.getXint(), p2.getYint()); + } + + public LineSegmentInt(int x1, int y1, int x2, int y2) { + this(new Point2DInt(x1, y1), new Point2DInt(x2, y2)); + } + + public LineSegmentInt(Point2DInt p1, Point2DInt p2) { + this.p1 = p1; + this.p2 = p2; + if (p1.equals(p2)) { + throw new IllegalArgumentException(); + } + assert p1 != null && p2 != null; + assert getLength() > 0; + assert this.getDistance(this) == 0; + } + + public boolean containsPoint(Point2D point) { + return side(point) == 0 && isBetween(point, p1, p2); + } + + public double side(Box box) { + final Point2DInt corners[] = box.getCorners(); + final double s0 = side(corners[0]); + final double s1 = side(corners[1]); + final double s2 = side(corners[2]); + final double s3 = side(corners[3]); + if (s0 > 0 && s1 > 0 && s2 > 0 && s3 > 0) { + return 1; + } + if (s0 < 0 && s1 < 0 && s2 < 0 && s3 < 0) { + return -1; + } + return 0; + } + + public boolean doesIntersectButNotSameExtremity(LineSegmentInt other) { + // assert sameExtremities(other) == false; + if (doesIntersect(other) == false) { + return false; + } + if (atLeastOneCommonExtremities(other)) { + return false; + } + return true; + } + + public boolean sameExtremities(LineSegmentInt other) { + if (p1.equals(other.p1) && p2.equals(other.p2)) { + return true; + } + if (p1.equals(other.p2) && p2.equals(other.p1)) { + return true; + } + return false; + } + + public boolean atLeastOneCommonExtremities(LineSegmentInt other) { + if (p1.equals(other.p1)) { + return true; + } + if (p1.equals(other.p2)) { + return true; + } + if (p2.equals(other.p1)) { + return true; + } + if (p2.equals(other.p2)) { + return true; + } + return false; + } + + public Point2DInt getCommonExtremities(LineSegmentInt other) { + if (p1.equals(other.p1)) { + return p1; + } + if (p1.equals(other.p2)) { + return p1; + } + if (p2.equals(other.p1)) { + return p2; + } + if (p2.equals(other.p2)) { + return p2; + } + return null; + } + + public Point2DInt getOtherExtremity(Point2DInt extremity1) { + if (extremity1 == null) { + throw new IllegalArgumentException(); + } + if (extremity1.equals(p1)) { + return p2; + } + if (extremity1.equals(p2)) { + return p1; + } + throw new IllegalArgumentException(); + } + + // Line2D + + @Override + public Point2DInt getP1() { + return p1; + } + + @Override + public Point2DInt getP2() { + return p2; + } + + @Override + public double getX1() { + return p1.getXint(); + } + + @Override + public double getX2() { + return p2.getXint(); + } + + @Override + public double getY1() { + return p1.getYint(); + } + + @Override + public double getY2() { + return p2.getYint(); + } + + public Point2DInt getTranslatedPoint(Point2DInt pointToBeTranslated) { + final int x = p2.getXint() - p1.getXint(); + final int y = p2.getYint() - p1.getYint(); + return new Point2DInt(pointToBeTranslated.getXint() + x, pointToBeTranslated.getYint() + y); + } + + public Point2DInt getCenter() { + return new Point2DInt((p1.getXint() + p2.getXint()) / 2, (p1.getYint() + p2.getYint()) / 2); + } + + public int getMinX() { + return Math.min(p1.getXint(), p2.getXint()); + } + + public int getMaxX() { + return Math.max(p1.getXint(), p2.getXint()); + } + + public int getMinY() { + return Math.min(p1.getYint(), p2.getYint()); + } + + public int getMaxY() { + return Math.max(p1.getYint(), p2.getYint()); + } + + public Point2DInt ortho(Point2D.Double orig, double d) { + final double vectX = p2.getY() - p1.getY(); + final double vectY = -(p2.getX() - p1.getX()); + final double pour = 1.0 * d / 100.0; + final double x = orig.x + vectX * pour; + final double y = orig.y + vectY * pour; + return new Point2DInt((int) Math.round(x), (int) Math.round(y)); + } + + public LineSegmentInt translate(int deltaX, int deltaY) { + return new LineSegmentInt(p1.translate(deltaX, deltaY), p2.translate(deltaX, deltaY)); + } + + public LineSegmentInt inflateXAlpha(InflateData inflateData) { + + final int xpos = inflateData.getPos(); + final int inflation = inflateData.getInflation(); + if (isHorizontal()) { + return new LineSegmentInt(p1.inflateX(inflateData), p2.inflateX(inflateData)); + } + if (getP1().getXint() == xpos && getP2().getXint() == xpos) { + return this.translate(inflation / 2, 0); + } + if (getP1().getXint() <= xpos && getP2().getXint() <= xpos) { + return this; + } + if (getP1().getXint() >= xpos && getP2().getXint() >= xpos) { + return this.translate(inflation, 0); + } + throw new UnsupportedOperationException(toString() + " " + inflateData); + } + + public LineSegmentInt inflateYAlpha(InflateData inflateData) { + final int ypos = inflateData.getPos(); + final int inflation = inflateData.getInflation(); + if (isVertical()) { + return new LineSegmentInt(p1.inflateY(inflateData), p2.inflateY(inflateData)); + } + if (getP1().getYint() == ypos && getP2().getYint() == ypos) { + return this.translate(0, inflation / 2); + } + if (getP1().getYint() <= ypos && getP2().getYint() <= ypos) { + return this; + } + if (getP1().getYint() >= ypos && getP2().getYint() >= ypos) { + return this.translate(0, inflation); + } + throw new UnsupportedOperationException(); + } + + @Override + public Point2DInt getSegIntersection(AbstractLineSegment other) { + final Point2D result = super.getSegIntersection(other); + if (result == null) { + return null; + } + return new Point2DInt((int) Math.round(result.getX()), (int) Math.round(result.getY())); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/Neighborhood.java b/src/net/sourceforge/plantuml/geom/Neighborhood.java new file mode 100644 index 000000000..fe16f357b --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Neighborhood.java @@ -0,0 +1,117 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +public class Neighborhood { + + final private double angle1; + final private double angle2; + final private Point2DInt center; + + public Neighborhood(Point2DInt center) { + this(center, 0, 0); + } + + public boolean is360() { + return angle1 == angle2; + } + + public Neighborhood(Point2DInt center, double angle1, double angle2) { + this.center = center; + this.angle1 = angle1; + this.angle2 = angle2; + } + + @Override + public String toString() { + final int a1 = (int) (angle1 * 180 / Math.PI); + final int a2 = (int) (angle2 * 180 / Math.PI); + return center + " " + a1 + " " + a2; + } + + public final Point2DInt getCenter() { + return center; + } + + public final double getMiddle() { + if (is360()) { + return angle1 + Math.PI; + } + double result = (angle1 + angle2) / 2; + if (angle2 < angle1) { + result += Math.PI; + } + return result; + } + + public boolean isInAngleStrict(double angle) { + if (angle < 0) { + throw new IllegalArgumentException(); + } + if (angle2 > angle1) { + return angle > angle1 && angle < angle2; + } + return angle > angle1 || angle < angle2; + } + + public boolean isInAngleLarge(double angle) { + if (angle < 0) { + throw new IllegalArgumentException(); + } + if (angle2 > angle1) { + return angle >= angle1 && angle <= angle2; + } + return angle >= angle1 || angle <= angle2; + } + + public boolean isAngleLimit(double angle) { + return angle == angle1 || angle == angle2; + } + + public Orientation getOrientationFrom(double angle) { + if (angle1 == angle2) { + throw new IllegalStateException(); + } + if (angle != angle1 && angle != angle2) { + throw new IllegalArgumentException("this=" + this + " angle=" + (int) (angle * 180 / Math.PI)); + } + assert angle == angle1 || angle == angle2; + + if (angle == angle1) { + return Orientation.MATH; + } + return Orientation.CLOCK; + + } +} diff --git a/src/net/sourceforge/plantuml/geom/Orientation.java b/src/net/sourceforge/plantuml/geom/Orientation.java new file mode 100644 index 000000000..c4dde8adb --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Orientation.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +public enum Orientation { + + CLOCK, MATH + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/geom/Point2DInt.java b/src/net/sourceforge/plantuml/geom/Point2DInt.java new file mode 100644 index 000000000..0009cb317 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Point2DInt.java @@ -0,0 +1,120 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.awt.geom.Point2D; + +public class Point2DInt extends Point2D implements Pointable { + + private final int x; + private final int y; + + @Override + public String toString() { + return "(" + x + "," + y + ")"; + } + + public Point2DInt(int x, int y) { + this.x = x; + this.y = y; + } + + public int getXint() { + return x; + } + + public int getYint() { + return y; + } + + @Override + public double getX() { + return x; + } + + @Override + public double getY() { + return y; + } + + @Override + public void setLocation(double x, double y) { + throw new UnsupportedOperationException(); + } + + public Point2DInt getPosition() { + return this; + } + + public Point2DInt translate(int deltaX, int deltaY) { + return new Point2DInt(x + deltaX, y + deltaY); + } + + public Point2DInt inflateX(int xpos, int inflation) { + if (inflation % 2 != 0) { + throw new IllegalArgumentException(); + } + if (x < xpos) { + return this; + } + if (x == xpos) { + // throw new IllegalArgumentException(); + return translate(inflation / 2, 0); + } + return translate(inflation, 0); + } + + public Point2DInt inflateX(InflateData inflateData) { + return inflateX(inflateData.getPos(), inflateData.getInflation()); + } + + public Point2DInt inflateY(InflateData inflateData) { + return inflateY(inflateData.getPos(), inflateData.getInflation()); + } + + public Point2DInt inflateY(int ypos, int inflation) { + if (inflation % 2 != 0) { + throw new IllegalArgumentException(); + } + if (y < ypos) { + return this; + } + if (y == ypos) { + // throw new IllegalArgumentException(); + return translate(0, inflation / 2); + } + return translate(0, inflation); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/Pointable.java b/src/net/sourceforge/plantuml/geom/Pointable.java new file mode 100644 index 000000000..cac4261b1 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Pointable.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +public interface Pointable { + Point2DInt getPosition(); +} diff --git a/src/net/sourceforge/plantuml/geom/Polyline.java b/src/net/sourceforge/plantuml/geom/Polyline.java new file mode 100644 index 000000000..6bc4b5ad4 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Polyline.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.List; + +public interface Polyline { + + List segments(); + + int nbSegments(); + + boolean doesTouch(Polyline other); + + double getLength(); + +} diff --git a/src/net/sourceforge/plantuml/geom/PolylineBreakeable.java b/src/net/sourceforge/plantuml/geom/PolylineBreakeable.java new file mode 100644 index 000000000..b421d1706 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/PolylineBreakeable.java @@ -0,0 +1,152 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PolylineBreakeable extends AbstractPolyline implements Polyline { + + static class Breakure { + private int d; + private int u; + + public Breakure(int u, int d) { + this.u = u; + this.d = d; + } + } + + private final List breakures = new ArrayList(); + + public PolylineBreakeable copy(Pointable newStart, Pointable newEnd) { + final PolylineBreakeable result = new PolylineBreakeable(newStart, newEnd); + result.breakures.addAll(this.breakures); + return result; + } + + public PolylineBreakeable(Pointable start, Pointable end) { + super(start, end); + } + + public List segments() { + if (breakures.size() == 0) { + return Collections.singletonList(new LineSegmentInt(getStart().getPosition(), getEnd().getPosition())); + } + final List result = new ArrayList(); + Point2DInt cur = getStart().getPosition(); + for (Breakure breakure : breakures) { + final Point2DInt next = getBreakurePoint(breakure); + result.add(new LineSegmentInt(cur, next)); + cur = next; + } + result.add(new LineSegmentInt(cur, getEnd().getPosition())); + assert nbSegments() == result.size(); + return Collections.unmodifiableList(result); + } + + private Point2DInt getBreakurePoint(Breakure breakure) { + final LineSegmentInt seg = new LineSegmentInt(getStart().getPosition(), getEnd().getPosition()); + return seg.ortho(seg.startTranslatedAsVector(breakure.u), breakure.d); + } + + public int nbSegments() { + return breakures.size() + 1; + } + + public List getFreedoms() { + final List allFreedom = new ArrayList(); + + for (final Breakure breakure : breakures) { + allFreedom.add(new XMoveable() { + @Override + public String toString() { + return super.toString() + " " + PolylineBreakeable.this.toString() + "(d)"; + } + + public void moveX(int delta) { + breakure.d += delta; + } + }); + allFreedom.add(new XMoveable() { + @Override + public String toString() { + return super.toString() + " " + PolylineBreakeable.this.toString() + "(u)"; + } + + public void moveX(int delta) { + breakure.u += delta; + } + }); + allFreedom.add(new XMoveable() { + @Override + public String toString() { + return super.toString() + " " + PolylineBreakeable.this.toString() + "(ud)"; + } + + public void moveX(int delta) { + breakure.u += delta; + breakure.d += delta; + } + }); + allFreedom.add(new XMoveable() { + @Override + public String toString() { + return super.toString() + " " + PolylineBreakeable.this.toString() + "(dud)"; + } + + public void moveX(int delta) { + breakure.u += delta; + breakure.d -= delta; + } + }); + } + + return Collections.unmodifiableList(allFreedom); + } + + public void insertBetweenPoint(int u, int d) { + breakures.add(new Breakure(u, d)); + } + + private void breakMore() { + if (breakures.size() == 1) { + final Breakure b = breakures.get(0); + insertBetweenPoint(b.u / 2, 0); + } + + } + +} diff --git a/src/net/sourceforge/plantuml/geom/PolylineImpl.java b/src/net/sourceforge/plantuml/geom/PolylineImpl.java new file mode 100644 index 000000000..fcc44e721 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/PolylineImpl.java @@ -0,0 +1,98 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class PolylineImpl extends AbstractPolyline implements Polyline { + + final private List intermediates = new ArrayList(); + + public PolylineImpl(Pointable start, Pointable end) { + super(start, end); + } + + public int nbSegments() { + return intermediates.size() + 1; + } + + public List segments() { + final List result = new ArrayList(); + Point2DInt cur = getStart().getPosition(); + for (Point2DInt intermediate : intermediates) { + result.add(new LineSegmentInt(cur, intermediate)); + cur = intermediate; + } + result.add(new LineSegmentInt(cur, getEnd().getPosition())); + return Collections.unmodifiableList(result); + } + + public void addIntermediate(Point2DInt intermediate) { + assert intermediates.contains(intermediate) == false; + intermediates.add(intermediate); + } + + public void inflate(InflationTransform transform) { + // final List segments = segments(); + // if (segments.size() == 1) { + // return; + // } + // intermediates.clear(); + // if (segments.size() == 2) { + // final Point2DInt p = segments.get(0).getP2(); + // intermediates.add(transform.inflatePoint2DInt(p)); + // } else { + // final List segmentsT = transform.inflate(segments); + // for (int i = 0; i < segmentsT.size() - 2; i++) { + // intermediates.add(segmentsT.get(i).getP2()); + // } + // + // } + + final List segments = transform.inflate(this.segments()); + // System.err.println("segments="+segments); + intermediates.clear(); + for (int i = 1; i < segments.size() - 1; i++) { + addIntermediate(segments.get(i).getP1()); + } + } + + public final Collection getIntermediates() { + return Collections.unmodifiableCollection(intermediates); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/Singularity.java b/src/net/sourceforge/plantuml/geom/Singularity.java new file mode 100644 index 000000000..ceabfd204 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/Singularity.java @@ -0,0 +1,152 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.TreeSet; + +public class Singularity { + + private final TreeSet angles = new TreeSet(); + + final private Point2DInt center; + + public Singularity(Point2DInt center) { + this.center = center; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(center.toString()); + for (Double a : angles) { + final int degree = (int) (a * 180 / Math.PI); + sb.append(' '); + sb.append(degree); + } + return sb.toString(); + } + + public void addLineSegment(LineSegmentInt seg) { + if (seg.getP1().equals(center)) { + angles.add(convertAngle(seg.getAngle())); + } else if (seg.getP2().equals(center)) { + angles.add(convertAngle(seg.getOppositeAngle())); + } else { + assert seg.side(center) == 0 : "side=" + seg.side(center) + " center=" + center + " seg=" + seg; + assert LineSegmentInt.isBetween(center, seg.getP1(), seg.getP2()); + addLineSegment(new LineSegmentInt(center, seg.getP1())); + addLineSegment(new LineSegmentInt(center, seg.getP2())); + } + assert betweenZeroAndTwoPi(); + + } + + static double convertAngle(double a) { + if (a < 0) { + return a + 2 * Math.PI; + } + return a; + } + + private boolean betweenZeroAndTwoPi() { + for (Double d : angles) { + assert d >= 0; + assert d < 2 * Math.PI; + } + return true; + } + + List getAngles() { + return new ArrayList(angles); + } + + public boolean crossing(Point2DInt direction1, Point2DInt direction2) { + final boolean result = crossingInternal(direction1, direction2); + assert result == crossingInternal(direction2, direction1); + return result; + } + + private boolean crossingInternal(Point2DInt direction1, Point2DInt direction2) { + if (angles.size() < 2) { + return false; + } + final double angle1 = convertAngle(new LineSegmentInt(center, direction1).getAngle()); + final double angle2 = convertAngle(new LineSegmentInt(center, direction2).getAngle()); + + Double last = null; + for (Double current : angles) { + if (last != null) { + assert last < current; + if (isBetween(angle1, last, current) && isBetween(angle2, last, current)) { + return false; + } + } + last = current; + } + final double first = angles.first(); + if ((angle1 <= first || angle1 >= last) && (angle2 <= first || angle2 >= last)) { + return false; + } + return true; + } + + private boolean isBetween(double test, double v1, double v2) { + assert v1 < v2; + return test >= v1 && test <= v2; + } + + protected final Point2DInt getCenter() { + return center; + } + + public void merge(Singularity other) { + this.angles.addAll(other.angles); + } + + public List getNeighborhoods() { + if (angles.size() == 0) { + return Collections.singletonList(new Neighborhood(center)); + } + final List result = new ArrayList(); + double last = angles.last(); + for (Double currentAngle : angles) { + result.add(new Neighborhood(center, last, currentAngle)); + last = currentAngle; + } + return Collections.unmodifiableList(result); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/SpiderWeb.java b/src/net/sourceforge/plantuml/geom/SpiderWeb.java new file mode 100644 index 000000000..286637407 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/SpiderWeb.java @@ -0,0 +1,181 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.Log; + +public class SpiderWeb { + + private final int pointsInCircle = 16; + private int nbRow; + private int nbCol; + + final private int widthCell; + final private int heightCell; + + final private int xMargin = 50; + final private int yMargin = 50; + + private final List lines = new ArrayList(); + + public SpiderWeb(int widthCell, int heightCell) { + Log.info("widthCell=" + widthCell + " heightCell=" + heightCell); + this.widthCell = widthCell; + this.heightCell = heightCell; + } + + public Point2DInt getMainPoint(int row, int col) { + return new Point2DInt(col * (widthCell + xMargin), row * (heightCell + yMargin)); + } + + public Collection getHangPoints(int row, int col) { + // final double dist = Math.pow(1.6, -row - 10) + Math.pow(1.5, -col - + // 10); + assert pointsInCircle % 4 == 0; + final List result = new ArrayList(); + final int dist = (int) Math.round(Math.sqrt(widthCell * widthCell + heightCell * heightCell) / 10); + for (int i = 0; i < pointsInCircle; i++) { + final Point2DInt main = getMainPoint(row, col); + final int x = main.getXint(); + final int y = main.getYint(); + if (i == 0) { + result.add(new Point2DInt(x + dist, y)); + } else if (i == pointsInCircle / 4) { + result.add(new Point2DInt(x, y + dist)); + } else if (i == 2 * pointsInCircle / 4) { + result.add(new Point2DInt(x - dist, y)); + } else if (i == 3 * pointsInCircle / 4) { + result.add(new Point2DInt(x, y - dist)); + } else { + final double angle = Math.PI * 2.0 * i / pointsInCircle; + final double x1 = x + dist * Math.cos(angle); + final double y1 = y + dist * Math.sin(angle); + result.add(new Point2DInt((int) Math.round(x1), (int) Math.round(y1))); + } + } + // System.err.println("getHangPoints="+result); + return result; + } + + public PolylineBreakeable addPolyline(int row1, int col1, int row2, int col2) { + // System.err.println("SpiderWeb : adding " + row1 + "," + col1 + " - " + // + row2 + "," + col2); + final PolylineBreakeable result = computePolyline(row1, col1, row2, col2); + // System.err.println("SpiderWeb : adding " + result); + if (result != null) { + lines.add(result); + } + return result; + } + + private PolylineBreakeable computePolyline(int row1, int col1, int row2, int col2) { + if (row1 > nbRow) { + nbRow = row1; + } + if (row2 > nbRow) { + nbRow = row2; + } + if (col1 > nbCol) { + nbCol = col1; + } + if (col2 > nbCol) { + nbCol = col2; + } + if (directLinkPossibleForGeometry(row1, col1, row2, col2)) { + // System.err.println("Geom OK"); + final PolylineBreakeable direct = new PolylineBreakeable(getMainPoint(row1, col1), getMainPoint(row2, col2)); + if (isCompatible(direct)) { + // System.err.println("Direct OK"); + return direct; + } + } + return bestLevel1Line(row1, col1, row2, col2); + } + + private boolean isCompatible(PolylineBreakeable toTest) { + for (PolylineBreakeable p : lines) { + if (p.doesTouch(toTest)) { + return false; + } + } + return true; + } + + private PolylineBreakeable bestLevel1Line(int row1, int col1, int row2, int col2) { + PolylineBreakeable result = null; + for (int u = 5; u <= 95; u += 5) { + for (int d = -200; d <= 200; d += 5) { + final PolylineBreakeable cur = new PolylineBreakeable(getMainPoint(row1, col1), + getMainPoint(row2, col2)); + cur.insertBetweenPoint(u, d); + if ((result == null || cur.getLength() < result.getLength()) && isCompatible(cur)) { + result = cur; + } + + } + } + return result; + } + + boolean directLinkPossibleForGeometry(int row1, int col1, int row2, int col2) { + final int rowMin = Math.min(row1, row2); + final int rowMax = Math.max(row1, row2); + final int colMin = Math.min(col1, col2); + final int colMax = Math.max(col1, col2); + final LineSegmentInt seg = new LineSegmentInt(col1, row1, col2, row2); + for (int r = rowMin; r <= rowMax; r++) { + for (int c = colMin; c <= colMax; c++) { + if (r == row1 && c == col1) { + continue; + } + if (r == row2 && c == col2) { + continue; + } + if (seg.containsPoint(new Point2DInt(c, r))) { + return false; + } + } + } + return true; + } + + final int getPointsInCircle() { + return pointsInCircle; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/geom/XMoveable.java b/src/net/sourceforge/plantuml/geom/XMoveable.java new file mode 100644 index 000000000..755dd76d1 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/XMoveable.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3830 $ + * + */ +package net.sourceforge.plantuml.geom; + +public interface XMoveable { + + void moveX(int delta); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/geom/kinetic/Frame.java b/src/net/sourceforge/plantuml/geom/kinetic/Frame.java new file mode 100644 index 000000000..29d64411a --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/Frame.java @@ -0,0 +1,116 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.geom.LineSegmentDouble; + +public class Frame { + + private double x; + private double y; + + private final int width; + private final int height; + + public Frame(double x, double y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + LineSegmentDouble getSide1() { + return new LineSegmentDouble(x, y, x, y + height); + } + + LineSegmentDouble getSide2() { + return new LineSegmentDouble(x, y, x + width, y); + } + + LineSegmentDouble getSide3() { + return new LineSegmentDouble(x + width, y, x + width, y + height); + } + + LineSegmentDouble getSide4() { + return new LineSegmentDouble(x, y + height, x + width, y + height); + } + + public Point2D getFrontierPointViewBy(Point2D point) { + final LineSegmentDouble seg = new LineSegmentDouble(point, getCenter()); + Point2D p = seg.getSegIntersection(getSide1()); + if (p != null) { + return p; + } + p = seg.getSegIntersection(getSide2()); + if (p != null) { + return p; + } + p = seg.getSegIntersection(getSide3()); + if (p != null) { + return p; + } + p = seg.getSegIntersection(getSide4()); + if (p != null) { + return p; + } + return null; + } + + private Point2D getCenter() { + return new Point2D.Double(x + width / 2.0, y + height / 2.0); + } + + public Point2D getMainCorner() { + return new Point2D.Double(x, y); + } + + public final double getX() { + return x; + } + + public final double getY() { + return y; + } + + public final int getWidth() { + return width; + } + + public final int getHeight() { + return height; + } + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/MoveObserver.java b/src/net/sourceforge/plantuml/geom/kinetic/MoveObserver.java new file mode 100644 index 000000000..a495a21d0 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/MoveObserver.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +public interface MoveObserver { + + public void pointMoved(Point2DCharge point); + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/Path.java b/src/net/sourceforge/plantuml/geom/kinetic/Path.java new file mode 100644 index 000000000..6cecb3c05 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/Path.java @@ -0,0 +1,162 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Path { + + private final Frame frame1; + private final Frame frame2; + private final List points1 = new ArrayList(); + // private final Map points2 = new + // HashMap(1000, (float).01); + private final Map points2 = new HashMap(); + + public Path(Frame f1, Frame f2) { + if (f1 == null || f2 == null) { + throw new IllegalArgumentException(); + } + this.frame1 = f1; + this.frame2 = f2; + updateCharges(); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append(frame1.getMainCorner()); + for (Point2DCharge p : points1) { + sb.append(' '); + sb.append(p); + } + sb.append(frame2.getMainCorner()); + return sb.toString(); + } + + private void updateCharges() { + for (Point2DCharge pt : points1) { + // pt.setCharge(1.0 / points1.size()); + pt.setCharge(1.0); + } + } + + private static final double MINDIST = 30; + + public void renderContinue() { + final List newPoints = new ArrayList(); + Point2D cur = frame1.getMainCorner(); + for (Point2DCharge pc : points1) { + final SegmentCutter segmentCutter = new SegmentCutter(cur, pc, MINDIST); + newPoints.addAll(segmentCutter.intermediates()); + cur = pc; + } + final SegmentCutter segmentCutter = new SegmentCutter(cur, frame2.getMainCorner(), MINDIST); + final List in = segmentCutter.intermediates(); + newPoints.addAll(in.subList(0, in.size() - 1)); + + points1.clear(); + points2.clear(); + for (Point2D pt : newPoints) { + addIntermediate(new Point2DCharge(pt.getX(), pt.getY())); + } + } + + public List segments() { + final List result = new ArrayList(); + Point2D cur = frame1.getMainCorner(); + for (Point2D pt : points1) { + result.add(new Line2D.Double(cur, pt)); + cur = pt; + } + result.add(new Line2D.Double(cur, frame2.getMainCorner())); + return Collections.unmodifiableList(result); + } + + public void addIntermediate(Point2DCharge point) { + assert points1.size() == points2.size(); + assert points1.contains(point) == false; + assert points2.containsKey(point) == false; + assert containsPoint2DCharge(point) == false; + points1.add(point); + points2.put(point, points2.size()); + assert points1.size() == points2.size(); + assert points1.contains(point); + assert points2.containsKey(point); + assert containsPoint2DCharge(point); + updateCharges(); + } + + public VectorForce getElasticForce(Point2DCharge point) { + final int idx = points1.indexOf(point); + if (idx == -1) { + throw new UnsupportedOperationException(); + } + final Point2D before = getPosition(idx - 1); + final Point2D after = getPosition(idx + 1); + final VectorForce f1 = new VectorForce(point, before); + final VectorForce f2 = new VectorForce(point, after); + return f1.plus(f2).multiply(0.2); + // return new VectorForce(0, 0); + } + + private Point2D getPosition(int idx) { + if (idx == -1) { + return frame1.getMainCorner(); + } + if (idx == points1.size()) { + return frame2.getMainCorner(); + } + return points1.get(idx); + } + + public boolean containsPoint2DCharge(Point2DCharge p) { + assert points1.contains(p) == points2.containsKey(p) : "p=" + p + "v1=" + points1.contains(p) + "v2=" + + points2.containsKey(p) + " points1=" + points1 + " points2=" + points2; + return points2.containsKey(p); + } + + public final Collection getPoints() { + assert points1.size() == points2.size(); + return Collections.unmodifiableCollection(points1); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/Point2DCharge.java b/src/net/sourceforge/plantuml/geom/kinetic/Point2DCharge.java new file mode 100644 index 000000000..427501bf9 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/Point2DCharge.java @@ -0,0 +1,101 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.awt.geom.Point2D; + +public class Point2DCharge extends Point2D.Double { + + private double charge = 1.0; + + private MoveObserver moveObserver = null; + + public Point2DCharge(double x, double y) { + super(x, y); + } + + public Point2DCharge(Point2D pt, double ch) { + super(pt.getX(), pt.getY()); + this.charge = ch; + } + + public void apply(VectorForce value) { + System.err.println("Applying " + value); + x += value.getX(); + y += value.getY(); + if (moveObserver != null) { + moveObserver.pointMoved(this); + } + } + + @Override + final public void setLocation(double x, double y) { + throw new UnsupportedOperationException(); + } + + @Override + final public void setLocation(Point2D p) { + throw new UnsupportedOperationException(); + } + + @Override + public String toString() { + return System.identityHashCode(this) + " " + String.format("[%8.2f %8.2f]", x, y); + } + + public final double getCharge() { + return charge; + } + + public final void setCharge(double charge) { + this.charge = charge; + } + + private final int hash = System.identityHashCode(this); + + @Override + public int hashCode() { + return hash; + } + + @Override + public boolean equals(Object obj) { + return this == obj; + } + + public final void setMoveObserver(MoveObserver moveObserver) { + this.moveObserver = moveObserver; + } + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/Quadrant.java b/src/net/sourceforge/plantuml/geom/kinetic/Quadrant.java new file mode 100644 index 000000000..af236a9af --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/Quadrant.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + +public class Quadrant { + + static final private int SIZE = 100; + + private final int x; + private final int y; + + public Quadrant(int x, int y) { + this.x = x; + this.y = y; + } + + public Quadrant(Point2DCharge pt) { + this((int) pt.getX() / SIZE, (int) pt.getY() / SIZE); + } + + @Override + public boolean equals(Object obj) { + final Quadrant other = (Quadrant) obj; + return x == other.x && y == other.y; + } + + @Override + public int hashCode() { + return x * 3571 + y; + } + + @Override + public String toString() { + return "" + x + "-" + y; + } + + public Collection neighbourhood() { + final Collection result = Arrays.asList(new Quadrant(x - 1, y - 1), new Quadrant(x, y - 1), + new Quadrant(x + 1, y - 1), new Quadrant(x - 1, y), this, new Quadrant(x + 1, y), new Quadrant(x - 1, + y + 1), new Quadrant(x, y + 1), new Quadrant(x + 1, y + 1)); + assert new HashSet(result).size() == 9; + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/QuadrantMapper.java b/src/net/sourceforge/plantuml/geom/kinetic/QuadrantMapper.java new file mode 100644 index 000000000..7cc74a516 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/QuadrantMapper.java @@ -0,0 +1,104 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class QuadrantMapper { + + private final Map quadrants = new HashMap(); + private final Map> setOfPoints = new HashMap>(); + + public void addPoint(Point2DCharge pt) { + if (quadrants.containsKey(pt)) { + throw new IllegalArgumentException(); + } + final Quadrant q = new Quadrant(pt); + quadrants.put(pt, q); + getSetOfPoints(q).add(pt); + assert getSetOfPoints(q).contains(pt); + assert getSetOfPoints(new Quadrant(pt)).contains(pt); + } + + public Set getAllPoints(Quadrant qt) { + return Collections.unmodifiableSet(getSetOfPoints(qt)); + } + + public Set getAllPoints() { + assert quadrants.keySet().equals(mergeOfSetOfPoints()); + return Collections.unmodifiableSet(quadrants.keySet()); + } + + private Set mergeOfSetOfPoints() { + final Set result = new HashSet(); + for (Set set : setOfPoints.values()) { + assert Collections.disjoint(set, result); + result.addAll(set); + } + return result; + } + + public void updatePoint(Point2DCharge pt) { + final Quadrant newQ = new Quadrant(pt); + final Quadrant old = quadrants.get(pt); + assert getSetOfPoints(old).contains(pt); + if (old.equals(newQ) == false) { + assert getSetOfPoints(newQ).contains(pt) == false; + assert getSetOfPoints(old).contains(pt); + final boolean remove = getSetOfPoints(old).remove(pt); + assert remove; + final boolean add = getSetOfPoints(newQ).add(pt); + assert add; + assert getSetOfPoints(newQ).contains(pt); + assert getSetOfPoints(old).contains(pt) == false; + quadrants.put(pt, newQ); + } + assert getSetOfPoints(new Quadrant(pt)).contains(pt); + } + + private HashSet getSetOfPoints(Quadrant q) { + HashSet result = setOfPoints.get(q); + if (result == null) { + result = new HashSet(); + setOfPoints.put(q, result); + } + return result; + + } + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/SegmentCutter.java b/src/net/sourceforge/plantuml/geom/kinetic/SegmentCutter.java new file mode 100644 index 000000000..b745bbeee --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/SegmentCutter.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +class SegmentCutter { + + private final List intermediates = new ArrayList(); + + public SegmentCutter(Point2D start, Point2D end, double maxDistance) { + final double d = end.distance(start); + if (d <= maxDistance) { + intermediates.add(end); + return; + } + int nb = 2; + while (d / nb > maxDistance) { + nb++; + } + final double deltaX = end.getX() - start.getX(); + final double deltaY = end.getY() - start.getY(); + for (int i = 1; i < nb; i++) { + intermediates.add(new Point2D.Double(start.getX() + i * deltaX / nb, start.getY() + i * deltaY / nb)); + } + intermediates.add(end); + } + + public List intermediates() { + return Collections.unmodifiableList(intermediates); + } + +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/VectorForce.java b/src/net/sourceforge/plantuml/geom/kinetic/VectorForce.java new file mode 100644 index 000000000..53f7a467c --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/VectorForce.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.awt.geom.Point2D; + +public class VectorForce { + + private final double x; + private final double y; + + public VectorForce(double x, double y) { + if (Double.isNaN(x) || Double.isNaN(y) || Double.isInfinite(x) || Double.isInfinite(y)) { + throw new IllegalArgumentException(); + } + this.x = x; + this.y = y; + } + + public VectorForce(Point2D src, Point2D dest) { + this(dest.getX() - src.getX(), dest.getY() - src.getY()); + } + + public VectorForce plus(VectorForce other) { + return new VectorForce(this.x + other.x, this.y + other.y); + } + + public VectorForce multiply(double v) { + return new VectorForce(x * v, y * v); + } + + @Override + public String toString() { + return String.format("{%8.2f %8.2f}", x, y); + } + + public VectorForce negate() { + return new VectorForce(-x, -y); + } + + public double length() { + return Math.sqrt(x * x + y * y); + } + + public VectorForce normaliseTo(double newLength) { + if (Double.isInfinite(newLength) || Double.isNaN(newLength)) { + throw new IllegalArgumentException(); + } + final double actualLength = length(); + if (actualLength == 0) { + return this; + } + final double f = newLength / actualLength; + return new VectorForce(x * f, y * f); + + } + + public final double getX() { + return x; + } + + public final double getY() { + return y; + } + + public double getLength() { + return Math.sqrt(x * x + y * y); + } +} diff --git a/src/net/sourceforge/plantuml/geom/kinetic/World.java b/src/net/sourceforge/plantuml/geom/kinetic/World.java new file mode 100644 index 000000000..1da50ca03 --- /dev/null +++ b/src/net/sourceforge/plantuml/geom/kinetic/World.java @@ -0,0 +1,171 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.geom.kinetic; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class World implements MoveObserver { + + private final List paths = new ArrayList(); + private final Map pathOfPoints = new HashMap(); + private final List frames = new ArrayList(); + + public void addFrame(Frame frame) { + this.frames.add(frame); + } + + public void addPath(Path path) { + this.paths.add(path); + } + + public VectorForce getElectricForce(Point2DCharge point) { + VectorForce result = new VectorForce(0, 0); + + final Quadrant quadrant = new Quadrant(point); + + for (Quadrant q : quadrant.neighbourhood()) { + for (Point2DCharge pc2 : quadrantMapper.getAllPoints(q)) { + final Path path = pathOfPoints.get(pc2); + if (path.containsPoint2DCharge(point)) { + continue; + } + result = result.plus(getElectricForce(point, pc2)); + } + } + return result; + } + + private VectorForce getElectricForceSlow(Point2DCharge point) { + VectorForce result = new VectorForce(0, 0); + + for (Path path : paths) { + if (path.containsPoint2DCharge(point)) { + continue; + } + for (Point2DCharge pc2 : path.getPoints()) { + result = result.plus(getElectricForce(point, pc2)); + } + } + return result; + } + + static private VectorForce getElectricForce(Point2DCharge onThis, Point2DCharge byThis) { + final double dist = onThis.distance(byThis); + if (dist == 0) { + return new VectorForce(0, 0); + } + final VectorForce result = new VectorForce(byThis.getX() - onThis.getX(), byThis.getY() - onThis.getY()); + double v = 100.0 * onThis.getCharge() * byThis.getCharge() / dist / dist; + return result.normaliseTo(v); + } + + static private VectorForce getAtomicForce(Point2DCharge onThis, Point2DCharge byThis) { + final double dist = onThis.distance(byThis); + if (dist == 0) { + return new VectorForce(0, 0); + } + final VectorForce result = new VectorForce(byThis.getX() - onThis.getX(), byThis.getY() - onThis.getY()); + double v = 1000 / dist / dist / dist; + if (v > 5) { + v = 5; + } + return result.normaliseTo(v); + } + + Map getForces() { + final Map result = new LinkedHashMap(); + for (Path path : paths) { + for (Point2DCharge pt : path.getPoints()) { + // final VectorForce elastic = new VectorForce(0, 0); + // final VectorForce elect = new VectorForce(0, 0); + final VectorForce elastic = path.getElasticForce(pt); + final VectorForce elect = getElectricForce(pt); + VectorForce force = elastic.plus(elect); + for (Frame f : frames) { + final Point2D inter = f.getFrontierPointViewBy(pt); + if (inter != null) { + final Point2DCharge pchar = new Point2DCharge(inter, 1); + force = force.plus(getAtomicForce(pt, pchar)); + } + } + result.put(pt, force); + } + } + + return result; + } + + public double onePass() { + double result = 0; + final Map forces = getForces(); + for (Map.Entry ent : forces.entrySet()) { + final VectorForce force = ent.getValue(); + result += force.getLength(); + ent.getKey().apply(force); + } + return result; + } + + public final Collection getPaths() { + return Collections.unmodifiableCollection(paths); + } + + private QuadrantMapper quadrantMapper; + + public void renderContinue() { + quadrantMapper = new QuadrantMapper(); + pathOfPoints.clear(); + for (Path path : paths) { + path.renderContinue(); + } + for (Path path : paths) { + for (Point2DCharge pt : path.getPoints()) { + pt.setMoveObserver(this); + quadrantMapper.addPoint(pt); + pathOfPoints.put(pt, path); + } + } + } + + public void pointMoved(Point2DCharge point) { + quadrantMapper.updatePoint(point); + } +} diff --git a/src/net/sourceforge/plantuml/graph/ALink.java b/src/net/sourceforge/plantuml/graph/ALink.java new file mode 100644 index 000000000..d259fcc4b --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/ALink.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +public interface ALink { + + int getDiffHeight(); + + ANode getNode1(); + + ANode getNode2(); + + public Object getUserData(); + +} diff --git a/src/net/sourceforge/plantuml/graph/ALinkImpl.java b/src/net/sourceforge/plantuml/graph/ALinkImpl.java new file mode 100644 index 000000000..c1dd65ece --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/ALinkImpl.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +public class ALinkImpl implements ALink { + + private final ANode node1; + private final ANode node2; + private final Object userData; + private final int diffHeight; + + @Override + public String toString() { + return "" + node1 + " -> " + node2; + } + + public ALinkImpl(ANode n1, ANode n2, int diffHeight, Object userData) { + this.node1 = n1; + this.node2 = n2; + this.userData = userData; + this.diffHeight = diffHeight; + } + + public int getDiffHeight() { + return diffHeight; + } + + public ANode getNode1() { + return node1; + } + + public ANode getNode2() { + return node2; + } + + public final Object getUserData() { + return userData; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/ANode.java b/src/net/sourceforge/plantuml/graph/ANode.java new file mode 100644 index 000000000..a8136dd95 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/ANode.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +public interface ANode { + + void setRow(int row); + + int getRow(); + + String getCode(); + + public Object getUserData(); + +} diff --git a/src/net/sourceforge/plantuml/graph/ANodeImpl.java b/src/net/sourceforge/plantuml/graph/ANodeImpl.java new file mode 100644 index 000000000..a56c8ef2c --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/ANodeImpl.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +public class ANodeImpl implements ANode { + + private int row = Integer.MIN_VALUE; + private final String code; + private Object userData; + + public ANodeImpl(String code) { + this.code = code; + } + + @Override + public int hashCode() { + return code.hashCode(); + } + + public int getRow() { + return row; + } + + public void setRow(int row) { + this.row = row; + } + + public final String getCode() { + return code; + } + + @Override + public String toString() { + return code + " " + getRow(); + } + + public Object getUserData() { + return userData; + } + + public void setUserData(Object userData) { + this.userData = userData; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java b/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java new file mode 100644 index 000000000..689d0b6f6 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/AbstractEntityImage.java @@ -0,0 +1,109 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.StringBounder; + +abstract class AbstractEntityImage { + + private final Entity entity; + + final private Color red = new Color(Integer.parseInt("A80036", 16)); + final private Color yellow = new Color(Integer.parseInt("FEFECE", 16)); + private final Color yellowNote = new Color(Integer.parseInt("FBFB77", 16)); + + final private Font font14 = new Font("SansSerif", Font.PLAIN, 14); + final private Font font17 = new Font("Courier", Font.BOLD, 17); + final private Color green = new Color(Integer.parseInt("ADD1B2", 16)); + final private Color violet = new Color(Integer.parseInt("B4A7E5", 16)); + final private Color blue = new Color(Integer.parseInt("A9DCDF", 16)); + final private Color rose = new Color(Integer.parseInt("EB937F", 16)); + + public AbstractEntityImage(Entity entity) { + if (entity == null) { + throw new IllegalArgumentException("entity null"); + } + this.entity = entity; + } + + public abstract Dimension2D getDimension(StringBounder stringBounder); + + public abstract void draw(Graphics2D g2d); + + protected final Entity getEntity() { + return entity; + } + + protected final Color getRed() { + return red; + } + + protected final Color getYellow() { + return yellow; + } + + protected final Font getFont17() { + return font17; + } + + protected final Font getFont14() { + return font14; + } + + protected final Color getGreen() { + return green; + } + + protected final Color getViolet() { + return violet; + } + + protected final Color getBlue() { + return blue; + } + + protected final Color getRose() { + return rose; + } + + protected final Color getYellowNote() { + return yellowNote; + } +} diff --git a/src/net/sourceforge/plantuml/graph/Board.java b/src/net/sourceforge/plantuml/graph/Board.java new file mode 100644 index 000000000..af01b8552 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Board.java @@ -0,0 +1,265 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class Board { + + private final List links; + private final Map initialDirection; + + private final Map nodesCols = new LinkedHashMap(); + + private int hashcodeValue; + private boolean hashcodeComputed = false; + + private Board(Board old) { + this.links = old.links; + this.initialDirection = old.initialDirection; + this.nodesCols.putAll(old.nodesCols); + } + + public Comparator getLinkComparator() { + return new LenghtLinkComparator(nodesCols); + } + + public boolean equals(Object o) { + final Board other = (Board) o; + if (this.links != other.links) { + return false; + } + final Iterator it1 = this.nodesCols.values().iterator(); + final Iterator it2 = other.nodesCols.values().iterator(); + assert this.nodesCols.size() == other.nodesCols.size(); + while (it1.hasNext()) { + if (it1.next().equals(it2.next()) == false) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + if (this.hashcodeComputed) { + return this.hashcodeValue; + } + this.hashcodeValue = 13; + for (Integer i : nodesCols.values()) { + this.hashcodeValue = this.hashcodeValue * 17 + i; + } + this.hashcodeComputed = true; + return this.hashcodeValue; + } + + public void normalize() { + int minRow = Integer.MAX_VALUE; + int minCol = Integer.MAX_VALUE; + int maxRow = Integer.MIN_VALUE; + int maxCol = Integer.MIN_VALUE; + for (Map.Entry ent : nodesCols.entrySet()) { + minRow = Math.min(minRow, ent.getKey().getRow()); + maxRow = Math.max(maxRow, ent.getKey().getRow()); + minCol = Math.min(minCol, ent.getValue()); + maxCol = Math.max(maxCol, ent.getValue()); + } + for (Map.Entry ent : nodesCols.entrySet()) { + if (minRow != 0) { + ent.getKey().setRow(ent.getKey().getRow() - minRow); + } + if (minCol != 0) { + ent.setValue(ent.getValue() - minCol); + } + } + } + + private void normalizeCol() { + final int minCol = Collections.min(nodesCols.values()); + + if (minCol != 0) { + for (Map.Entry ent : nodesCols.entrySet()) { + ent.setValue(ent.getValue() - minCol); + } + } + } + + void internalMove(String code, int newCol) { + hashcodeComputed = false; + for (ANode n : nodesCols.keySet()) { + if (n.getCode().equals(code)) { + nodesCols.put(n, newCol); + return; + } + } + } + + public Board copy() { + return new Board(this); + } + + public Board(List nodes, List links) { + for (ANode n : nodes) { + addInRow(n); + } + this.links = Collections.unmodifiableList(new ArrayList(links)); + this.initialDirection = new HashMap(); + for (ALink link : links) { + this.initialDirection.put(link, getDirection(link)); + } + } + + public int getInitialDirection(ALink link) { + return initialDirection.get(link); + } + + public int getDirection(ALink link) { + return getCol(link.getNode2()) - getCol(link.getNode1()); + } + + private void addInRow(ANode n) { + hashcodeComputed = false; + int col = 0; + while (true) { + if (getNodeAt(n.getRow(), col) == null) { + nodesCols.put(n, col); + assert getNodeAt(n.getRow(), col) == n; + return; + } + col++; + } + } + + public Collection getNodes() { + return Collections.unmodifiableCollection(nodesCols.keySet()); + } + + public Collection getNodesInRow(int row) { + final List result = new ArrayList(); + for (ANode n : nodesCols.keySet()) { + if (n.getRow() == row) { + result.add(n); + } + } + return Collections.unmodifiableCollection(result); + } + + public final List getLinks() { + return Collections.unmodifiableList(links); + } + + public int getCol(ANode n) { + return nodesCols.get(n); + } + + public void applyMove(Move move) { + final ANode piece = getNodeAt(move.getRow(), move.getCol()); + if (piece == null) { + throw new IllegalArgumentException(); + } + final ANode piece2 = getNodeAt(move.getRow(), move.getNewCol()); + nodesCols.put(piece, move.getNewCol()); + if (piece2 != null) { + nodesCols.put(piece2, move.getCol()); + } + normalizeCol(); + hashcodeComputed = false; + } + + public Collection getAllPossibleMoves() { + final List result = new ArrayList(); + for (Map.Entry ent : nodesCols.entrySet()) { + final int row = ent.getKey().getRow(); + final int col = ent.getValue(); + result.add(new Move(row, col, -1)); + result.add(new Move(row, col, 1)); + } + return result; + } + + public ANode getNodeAt(int row, int col) { + for (Map.Entry ent : nodesCols.entrySet()) { + if (ent.getKey().getRow() == row && ent.getValue().intValue() == col) { + return ent.getKey(); + } + } + return null; + } + + public Set getConnectedNodes(ANode root, int level) { + if (level < 0) { + throw new IllegalArgumentException(); + } + if (level == 0) { + return Collections.singleton(root); + } + final Set result = new HashSet(); + if (level == 1) { + for (ALink link : links) { + if (link.getNode1() == root) { + result.add(link.getNode2()); + } else if (link.getNode2() == root) { + result.add(link.getNode1()); + } + + } + } else { + for (ANode n : getConnectedNodes(root, level - 1)) { + result.addAll(getConnectedNodes(n, 1)); + } + } + return Collections.unmodifiableSet(result); + } + + public Set getAllLinks(Set nodes) { + final Set result = new HashSet(); + for (ALink link : links) { + if (nodes.contains(link.getNode1()) || nodes.contains(link.getNode2())) { + result.add(link); + } + } + return Collections.unmodifiableSet(result); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/BoardCollection.java b/src/net/sourceforge/plantuml/graph/BoardCollection.java new file mode 100644 index 000000000..ca35e3629 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/BoardCollection.java @@ -0,0 +1,126 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.List; + +public class BoardCollection { + + static class Entry implements Comparable { + final private Board board; + final private double cost; + private boolean explored; + + public Entry(Board b, CostComputer costComputer) { + this.board = b; + if (costComputer != null) { + this.cost = costComputer.getCost(b); + } else { + this.cost = 0; + } + } + + public int compareTo(Entry other) { + return (int) Math.signum(this.cost - other.cost); + } + + @Override + public boolean equals(Object obj) { + final Entry other = (Entry) obj; + return board.equals(other.board); + } + + @Override + public int hashCode() { + return board.hashCode(); + } + + } + + private final SortedCollection all = new SortedCollectionArrayList(); + + private final CostComputer costComputer; + + public BoardCollection(CostComputer costComputer) { + this.costComputer = costComputer; + } + + public int size() { + return all.size(); + } + + public Board getAndSetExploredSmallest() { + for (Entry ent : all) { + if (ent.explored == false) { + ent.explored = true; + assert costComputer.getCost(ent.board) == ent.cost; + // System.err.println("Peeking " + ent.cost); + return ent.board; + } + } + return null; + } + + public double getBestCost() { + for (Entry ent : all) { + return ent.cost; + } + return 0; + } + + public Board getBestBoard() { + for (Entry ent : all) { + return ent.board; + } + return null; + } + + public List getCosts() { + final List result = new ArrayList(); + for (Entry ent : all) { + result.add(costComputer.getCost(ent.board)); + } + return result; + } + + public void add(Board b) { + all.add(new Entry(b, costComputer)); + } + + public boolean contains(Board b) { + return all.contains(new Entry(b, null)); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/BoardExplorer.java b/src/net/sourceforge/plantuml/graph/BoardExplorer.java new file mode 100644 index 000000000..e5e41e4f6 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/BoardExplorer.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.HashSet; +import java.util.Set; + +public class BoardExplorer { + + private final BoardCollection all = new BoardCollection(new KenavoCostComputer()); + + public BoardExplorer(Board init) { + all.add(init); + } + + public double getBestCost() { + return all.getBestCost(); + } + + public Board getBestBoard() { + return all.getBestBoard(); + } + + public int collectionSize() { + return all.size(); + } + + public boolean onePass() { + final Board smallest = all.getAndSetExploredSmallest(); + if (smallest == null) { + return true; + } + final Set moves = nextBoards(smallest); + for (Board newBoard : moves) { + if (all.contains(newBoard)) { + continue; + } + all.add(newBoard); + } + return false; + } + + public Set nextBoards(Board board) { + final Set result = new HashSet(); + for (Move m : board.getAllPossibleMoves()) { + final Board copy = board.copy(); + copy.applyMove(m); + result.add(copy); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/CostComputer.java b/src/net/sourceforge/plantuml/graph/CostComputer.java new file mode 100644 index 000000000..a6a362789 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/CostComputer.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +public interface CostComputer { + + double getCost(Board board); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graph/Elastane.java b/src/net/sourceforge/plantuml/graph/Elastane.java new file mode 100644 index 000000000..3cb835eda --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Elastane.java @@ -0,0 +1,365 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4626 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.geom.Box; +import net.sourceforge.plantuml.geom.CollectionUtils; +import net.sourceforge.plantuml.geom.Point2DInt; +import net.sourceforge.plantuml.geom.PolylineBreakeable; +import net.sourceforge.plantuml.geom.XMoveable; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +public class Elastane { + + private static final int STEP = 4; + private static final int OUTER_BOX = 20; + + final private Color red = new Color(Integer.parseInt("A80036", 16)); + + private final Galaxy4 galaxy; + + private final double margin = 30; + + private int minX = Integer.MAX_VALUE; + private int maxX = Integer.MIN_VALUE; + private int minY = Integer.MAX_VALUE; + private int maxY = Integer.MIN_VALUE; + + Elastane(Galaxy4 galaxy) { + this.galaxy = galaxy; + } + + private final Map boxes = new LinkedHashMap(); + private final Map lines = new LinkedHashMap(); + + public void addBox(ANode node, int w, int h) { + final int row = node.getRow(); + final int col = galaxy.getBoard().getCol(node); + final Point2DInt pos = galaxy.getMainPoint(row, col); + final Box box = new Box(pos.getXint() - w / 2, pos.getYint() - h / 2, w, h); + boxes.put(node, box); + assert boxOverlap() == false; + } + + private double getCost() { + if (boxOverlap()) { + return Double.MAX_VALUE; + } + double result = 0; + for (ALink alink : galaxy.getLines().keySet()) { + final PolylineBreakeable orig = lines.get(alink); + final PolylineBreakeable p = orig; + result += getLength(p); + final Box b1 = boxes.get(alink.getNode1()); + final Box b2 = boxes.get(alink.getNode2()); + result += getCostBoxIntersect(p, b1, b2); + + for (ALink alink2 : galaxy.getLines().keySet()) { + if (alink == alink2) { + continue; + } + final PolylineBreakeable other = lines.get(alink2); + if (p.doesTouch(other)) { + result += getLength(other); + // return Double.MAX_VALUE; + } + // result += p.getDistance(other); + } + } + + return result; + } + + private double getLength(final PolylineBreakeable mutedPolyline) { + final double len = mutedPolyline.getLength(); + assert len > 0; + return Math.log(1 + len); + } + + private double getCostBoxIntersect(PolylineBreakeable polyline, Box b1, Box b2) { + double result = 0; + for (Box b : boxes.values()) { + if (b == b1 || b == b2) { + continue; + } + if (polyline.intersectBox(b)) { + final double dist = polyline.getDistance(b); + assert dist >= 0; + assert dist != Double.MAX_VALUE; + // System.err.println("dist=" + dist + " exp=" + (100000 - + // dist)); + result += 100000 - dist; + } + + } + return result; + } + + private void initLines() { + for (ALink alink : galaxy.getLines().keySet()) { + final PolylineBreakeable p = galaxy.getPolyline(alink); + final Box b1 = boxes.get(alink.getNode1()); + final Box b2 = boxes.get(alink.getNode2()); + lines.put(alink, p.copy(b1, b2)); + } + + } + + private boolean boxOverlap() { + final List all = new ArrayList(); + for (Box b : boxes.values()) { + all.add(b.outerBox(OUTER_BOX)); + } + for (int i = 0; i < all.size() - 1; i++) { + for (int j = i + 1; j < all.size(); j++) { + if (all.get(i).intersectBox(all.get(j))) { + return true; + } + } + } + return false; + } + + private void moveX(Collection boxes, int delta, double initCost, boolean trace) { + for (XMoveable b : boxes) { + b.moveX(delta); + } + // if (trace) { + // final double diff = getCost() - initCost; + // System.err.println("moving " + boxes + " " + delta + " diff=" + + // diff); + // } + // for (Map.Entry entry : lines.entrySet()) { + // if (isConcerned(entry.getKey(), boxes)) { + // entry.getValue().moveX(delta); + // } + // + // } + } + + private boolean isConcerned(ALink link, Collection moved) { + final Box b1 = boxes.get(link.getNode1()); + final Box b2 = boxes.get(link.getNode2()); + return moved.contains(b1) && moved.contains(b2); + } + + private boolean onePass(Collection> subLists) { + boolean changed = false; + for (Collection toMove : subLists) { + final double initCost = getCost(); + + assert reversable(initCost, toMove); + + moveX(toMove, STEP, initCost, true); + if (getCost() < initCost) { + changed = true; + } else { + moveX(toMove, -STEP, initCost, false); + moveX(toMove, -STEP, initCost, true); + if (getCost() < initCost) { + changed = true; + } else { + moveX(toMove, STEP, initCost, false); + assert getCost() == initCost : "c1=" + getCost() + " init=" + initCost; + } + } + assert getCost() <= initCost; + + } + // System.err.println("COSTB=" + getCost()); + return changed; + } + + private boolean reversable(double initCost, Collection toMove) { + moveX(toMove, STEP, 0, false); + moveX(toMove, -STEP, 0, false); + assert getCost() == initCost; + moveX(toMove, STEP, 0, false); + moveX(toMove, -STEP * 2, 0, false); + moveX(toMove, STEP, 0, false); + assert getCost() == initCost; + return true; + } + + private Collection convertANodeSet(Set nodesSet, Map> linkMoveables) { + final Collection result = new HashSet(); + for (ANode n : nodesSet) { + assert boxes.get(n) != null; + result.add(boxes.get(n)); + } + // for (ALink link : galaxy.getBoard().getAllLinks(nodesSet)) { + // result.addAll(linkMoveables.get(link)); + // + // } + return result; + } + + public void draw(final Graphics2D g2d) { + final AffineTransform at = g2d.getTransform(); + g2d.translate(-minX + margin, -minY + margin); + + g2d.setColor(red); + for (Map.Entry ent : lines.entrySet()) { + final ALink alink = ent.getKey(); + final Link l = (Link) alink.getUserData(); + final GeneralPathFactory factory = new GeneralPathFactory(l.getType()); + final Box b1 = boxes.get(alink.getNode1()); + final Box b2 = boxes.get(alink.getNode2()); + final PolylineBreakeable polyline = ent.getValue(); + final Shape shape = factory.getLink(polyline, b1, b2); + + final String label = l.getLabel(); + if (label != null) { + final Point2DInt center = polyline.getFirst().getCenter(); + final TextBlock textBlock = TextBlockUtils.create(Arrays.asList(label), g2d.getFont(), Color.BLACK, + HorizontalAlignement.LEFT); + final Dimension2D dim = textBlock.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + textBlock.drawTOBEREMOVED(g2d, center.getXint() - dim.getWidth() / 2, center.getYint() - dim.getHeight() / 2); + } + + g2d.setColor(red); + g2d.draw(shape); + } + + g2d.setColor(Color.BLACK); + for (Map.Entry ent : boxes.entrySet()) { + final ANode node = ent.getKey(); + final AbstractEntityImage image = images(node.getRow(), galaxy.getBoard().getCol(node)); + assert image != null; + final Box box = ent.getValue(); + g2d.translate(box.getX(), box.getY()); + image.draw(g2d); + g2d.translate(-box.getX(), -box.getY()); + } + g2d.setTransform(at); + } + + public void init() { + initLines(); + final Set> nodesGroups = new HashSet>(); + final Collection nodes = galaxy.getBoard().getNodes(); + for (ANode root : nodes) { + for (int i = 0; i < galaxy.getBoard().getLinks().size(); i++) { + final Set group = galaxy.getBoard().getConnectedNodes(root, i); + if (group.size() < nodes.size()) { + nodesGroups.add(group); + } + } + } + final Collection> xmoveableGroups = new ArrayList>(); + final Map> linkMoveables = new HashMap>(); + + for (Map.Entry entry : lines.entrySet()) { + final PolylineBreakeable p = entry.getValue(); + final List freedoms = p.getFreedoms(); + // System.err.println("freedoms=" + freedoms); + if (freedoms.size() > 0) { + linkMoveables.put(entry.getKey(), freedoms); + // xmoveableGroups.addAll(CollectionUtils.selectUpTo(freedoms, + // freedoms.size())); + xmoveableGroups.addAll(CollectionUtils.selectUpTo(freedoms, 1)); + } + } + + for (Set nodesSet : nodesGroups) { + xmoveableGroups.add(convertANodeSet(nodesSet, linkMoveables)); + } + + assert getCost() != Double.MAX_VALUE; + for (int i = 0; i < 3000; i++) { + final boolean changed = onePass(xmoveableGroups); + if (changed == false) { + break; + } + } + + for (Box box : boxes.values()) { + minX = Math.min(minX, box.getMinX()); + maxX = Math.max(maxX, box.getMaxX()); + minY = Math.min(minY, box.getMinY()); + maxY = Math.max(maxY, box.getMaxY()); + } + + for (PolylineBreakeable polyline : lines.values()) { + minX = Math.min(minX, polyline.getMinX()); + maxX = Math.max(maxX, polyline.getMaxX()); + minY = Math.min(minY, polyline.getMinY()); + maxY = Math.max(maxY, polyline.getMaxY()); + } + + } + + private AbstractEntityImage images(int r, int c) { + final ANode n = galaxy.getBoard().getNodeAt(r, c); + if (n == null) { + return null; + } + return new EntityImageFactory().createEntityImage((Entity) n.getUserData()); + } + + public Dimension2D getDimension() { + final Dimension2DDouble dim = new Dimension2DDouble(maxX - minX + 2 * margin, maxY - minY + 2 * margin); + Log.info("Dim=" + dim); + return dim; + } + + // private Point2DInt transform(Point2DInt src) { + // return new Point2DInt(xMargin + widthCell / 2 + src.getXint() * + // (widthCell + xMargin), yMargin + heightCell / 2 + // + src.getYint() * (heightCell + yMargin)); + // } + +} diff --git a/src/net/sourceforge/plantuml/graph/ElectricCharge.java b/src/net/sourceforge/plantuml/graph/ElectricCharge.java new file mode 100644 index 000000000..4d273e8e4 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/ElectricCharge.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.geom.Point2D; + +public class ElectricCharge { + + private boolean moveable; + private final Point2D position; + private final double charge; + + public ElectricCharge(double x, double y, double charge) { + this.position = new Point2D.Double(x, y); + this.charge = charge; + } + + public Point2D getPosition() { + return position; + } + + public double getCharge() { + return charge; + } + + public final boolean isMoveable() { + return moveable; + } + + public final void setMoveable(boolean moveable) { + this.moveable = moveable; + } + + public void move(double deltax, double deltay) { + position.setLocation(position.getX() + deltax, position.getY() + deltay); + } +} diff --git a/src/net/sourceforge/plantuml/graph/ElectricWord.java b/src/net/sourceforge/plantuml/graph/ElectricWord.java new file mode 100644 index 000000000..d6134f206 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/ElectricWord.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ElectricWord { + + private List charges = new ArrayList(); + + public ElectricWord(Rectangle2D playingZone) { + + } + + public void addGlueArea(Rectangle2D glue) { + + } + + public void addCharge(ElectricCharge charge) { + + } + + public void addCharges(Collection charges) { + + } + + public Point2D getForceAt(Point2D position, double charge, Collection ignoredCharges) { + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageActivity.java b/src/net/sourceforge/plantuml/graph/EntityImageActivity.java new file mode 100644 index 000000000..91bb80c46 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageActivity.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4959 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +class EntityImageActivity extends AbstractEntityImage { + + final private TextBlock text; + + private final int xMargin = 10; + private final int yMargin = 6; + + public EntityImageActivity(Entity entity) { + super(entity); + this.text = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D dim = text.calculateDimension(stringBounder); + return Dimension2DDouble.delta(dim, 2*xMargin, 2*yMargin); + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + + final int width = (int) dimTotal.getWidth(); + final int height = (int) dimTotal.getHeight(); + + final Polygon p = new Polygon(); + p.addPoint(0, yMargin * 2); + p.addPoint(xMargin * 2, 0); + + p.addPoint(width - 2 * xMargin, 0); + p.addPoint(width, 2 * yMargin); + + p.addPoint(width, height - 2 * yMargin); + p.addPoint(width - 2 * xMargin, height); + + p.addPoint(xMargin * 2, height); + p.addPoint(0, height - 2 * yMargin); + + g2d.setColor(getYellow()); + g2d.fill(p); + // g2d.fillRect(0, 0, width, height); + + g2d.setColor(getRed()); + g2d.draw(p); + // g2d.drawRect(0, 0, width - 1, height - 1); + g2d.setColor(Color.BLACK); + text.drawTOBEREMOVED(g2d, xMargin, yMargin); + + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageActivityBar.java b/src/net/sourceforge/plantuml/graph/EntityImageActivityBar.java new file mode 100644 index 000000000..aafb2ca30 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageActivityBar.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.StringBounder; + +class EntityImageActivityBar extends AbstractEntityImage { + + private final int width = 100; + private final int height = 8; + + public EntityImageActivityBar(Entity entity) { + super(entity); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + return new Dimension2DDouble(width, height); + } + + @Override + public void draw(Graphics2D g2d) { + g2d.setColor(Color.BLACK); + g2d.fillRect(0, 0, width, height); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageActivityBranch.java b/src/net/sourceforge/plantuml/graph/EntityImageActivityBranch.java new file mode 100644 index 000000000..ce06033b5 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageActivityBranch.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.StringBounder; + +class EntityImageActivityBranch extends AbstractEntityImage { + + private final int size = 10; + + public EntityImageActivityBranch(Entity entity) { + super(entity); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + return new Dimension2DDouble(size * 2, size * 2); + } + + @Override + public void draw(Graphics2D g2d) { + final Polygon p = new Polygon(); + p.addPoint(size, 0); + p.addPoint(size * 2, size); + p.addPoint(size, size * 2); + p.addPoint(0, size); + + g2d.setColor(getYellow()); + g2d.fill(p); + g2d.setColor(getRed()); + g2d.draw(p); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageActivityCircle.java b/src/net/sourceforge/plantuml/graph/EntityImageActivityCircle.java new file mode 100644 index 000000000..10912dd57 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageActivityCircle.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.StringBounder; + +class EntityImageActivityCircle extends AbstractEntityImage { + + private final int diameterExternal; + private final int diameterInternal; + + public EntityImageActivityCircle(Entity entity, int diameterExternal, int diameterInternal) { + super(entity); + this.diameterExternal = diameterExternal; + this.diameterInternal = diameterInternal; + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + return new Dimension2DDouble(diameterExternal, diameterExternal); + } + + @Override + public void draw(Graphics2D g2d) { + g2d.setColor(Color.BLACK); + final int delta = diameterExternal - diameterInternal + 1; + g2d.drawOval(0, 0, diameterExternal, diameterExternal); + g2d.fillOval(delta / 2, delta / 2, diameterInternal, diameterInternal); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageActor.java b/src/net/sourceforge/plantuml/graph/EntityImageActor.java new file mode 100644 index 000000000..318f14b17 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageActor.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4189 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.StickMan; + +class EntityImageActor extends AbstractEntityImage { + + final private TextBlock name; + final private StickMan stickman; + + public EntityImageActor(Entity entity) { + super(entity); + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + this.stickman = new StickMan(getYellow(), getRed()); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D nameDim = name.calculateDimension(stringBounder); + final double manWidth = stickman.getPreferredWidth(stringBounder); + final double manHeight = stickman.getPreferredHeight(stringBounder); + return new Dimension2DDouble(Math.max(manWidth, nameDim.getWidth()), manHeight + nameDim.getHeight()); + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D nameDim = name.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + + final double manWidth = stickman.getPreferredWidth(StringBounderUtils.asStringBounder(g2d)); + final double manHeight = stickman.getPreferredHeight(StringBounderUtils.asStringBounder(g2d)); + + final double manX = (dimTotal.getWidth() - manWidth) / 2; + + g2d.setColor(Color.WHITE); + g2d.fill(new Rectangle2D.Double(0, 0, dimTotal.getWidth(), dimTotal.getHeight())); + + g2d.translate(manX, 0); + // stickman.draw(g2d); + g2d.translate(-manX, 0); + + g2d.setColor(Color.BLACK); + name.drawTOBEREMOVED(g2d, (dimTotal.getWidth() - nameDim.getWidth()) / 2, manHeight); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageCircleInterface.java b/src/net/sourceforge/plantuml/graph/EntityImageCircleInterface.java new file mode 100644 index 000000000..732218298 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageCircleInterface.java @@ -0,0 +1,90 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5343 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.CircleInterface; + +class EntityImageCircleInterface extends AbstractEntityImage { + + final private TextBlock name; + final private CircleInterface circleInterface; + + public EntityImageCircleInterface(Entity entity) { + super(entity); + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + this.circleInterface = new CircleInterface(getYellow(), getRed()); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D nameDim = name.calculateDimension(stringBounder); + final double manWidth = circleInterface.getPreferredWidth(stringBounder); + final double manHeight = circleInterface.getPreferredHeight(stringBounder); + return new Dimension2DDouble(Math.max(manWidth, nameDim.getWidth()), manHeight + nameDim.getHeight()); + } + + @Override + public void draw(Graphics2D g2d) { + throw new UnsupportedOperationException(); +// final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); +// final Dimension2D nameDim = name.calculateDimension(StringBounderUtils.asStringBounder(g2d)); +// +// final double manWidth = circleInterface.getPreferredWidth(StringBounderUtils.asStringBounder(g2d)); +// final double manHeight = circleInterface.getPreferredHeight(StringBounderUtils.asStringBounder(g2d)); +// +// final double manX = (dimTotal.getWidth() - manWidth) / 2; +// +// g2d.setColor(Color.WHITE); +// g2d.fill(new Rectangle2D.Double(0, 0, dimTotal.getWidth(), dimTotal.getHeight())); +// +// g2d.translate(manX, 0); +// circleInterface.draw(g2d); +// g2d.translate(-manX, 0); +// +// g2d.setColor(Color.BLACK); +// name.drawTOBEREMOVED(g2d, (dimTotal.getWidth() - nameDim.getWidth()) / 2, manHeight); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageClass.java b/src/net/sourceforge/plantuml/graph/EntityImageClass.java new file mode 100644 index 000000000..c3722e00c --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageClass.java @@ -0,0 +1,153 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5386 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.graphic.CircledCharacter; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +class EntityImageClass extends AbstractEntityImage { + + final private TextBlock name; + final private MethodsOrFieldsArea methods; + final private MethodsOrFieldsArea fields; + final private CircledCharacter circledCharacter; + + private final int xMargin = 10; + private final int yMargin = 6; + + public EntityImageClass(Entity entity) { + super(entity); + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + this.methods = new MethodsOrFieldsArea(entity.methods2(), getFont14()); + this.fields = new MethodsOrFieldsArea(entity.fields2(), getFont14()); + + circledCharacter = getCircledCharacter(entity); + + } + + private CircledCharacter getCircledCharacter(Entity entity) { + // if (entity.getStereotype() != null) { + // return new CircledCharacter(entity.getStereotype().getCharacter(), + // font, entity.getStereotype().getColor(), + // red, Color.BLACK); + // } + final double radius = 10; + if (entity.getType() == EntityType.ABSTRACT_CLASS) { + return new CircledCharacter('A', radius, getFont17(), getBlue(), getRed(), Color.BLACK); + } + if (entity.getType() == EntityType.CLASS) { + return new CircledCharacter('C', radius, getFont17(), getGreen(), getRed(), Color.BLACK); + } + if (entity.getType() == EntityType.INTERFACE) { + return new CircledCharacter('I', radius, getFont17(), getViolet(), getRed(), Color.BLACK); + } + if (entity.getType() == EntityType.ENUM) { + return new CircledCharacter('E', radius, getFont17(), getRose(), getRed(), Color.BLACK); + } + assert false; + return null; + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D dimName = getNameDimension(stringBounder); + final Dimension2D dimMethods = methods.calculateDimension(stringBounder); + final Dimension2D dimFields = fields.calculateDimension(stringBounder); + final double width = Math.max(Math.max(dimMethods.getWidth(), dimFields.getWidth()), dimName.getWidth()) + 2 + * xMargin; + final double height = dimMethods.getHeight() + dimFields.getHeight() + dimName.getHeight() + 6 * yMargin; + return new Dimension2DDouble(width, height); + } + + private Dimension2D getNameDimension(StringBounder stringBounder) { + final Dimension2D nameDim = name.calculateDimension(stringBounder); + if (circledCharacter == null) { + return nameDim; + } + return new Dimension2DDouble(nameDim.getWidth() + getCircledWidth(stringBounder), Math.max(nameDim.getHeight(), + circledCharacter.getPreferredHeight(stringBounder))); + } + + private double getCircledWidth(StringBounder stringBounder) { + if (circledCharacter == null) { + return 0; + } + return circledCharacter.getPreferredWidth(stringBounder) + 3; + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D dimName = getNameDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D dimFields = fields.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + + final int width = (int) dimTotal.getWidth(); + final int height = (int) dimTotal.getHeight(); + g2d.setColor(getYellow()); + g2d.fillRect(0, 0, width, height); + + g2d.setColor(getRed()); + g2d.drawRect(0, 0, width - 1, height - 1); + + final double line1 = dimName.getHeight() + 2 * yMargin; + final double line2 = dimName.getHeight() + dimFields.getHeight() + 4 * yMargin; + + g2d.drawLine(0, (int) line1, width, (int) line1); + g2d.drawLine(0, (int) line2, width, (int) line2); + + final double circledWidth = getCircledWidth(StringBounderUtils.asStringBounder(g2d)); + g2d.setColor(Color.BLACK); + name.drawTOBEREMOVED(g2d, xMargin + circledWidth, yMargin); + fields.drawTOBEREMOVED(g2d, xMargin, line1 + yMargin); + methods.drawTOBEREMOVED(g2d, xMargin, line2 + yMargin); + + if (circledCharacter != null) { + circledCharacter.draw(g2d, xMargin, yMargin); + } + + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageComponent.java b/src/net/sourceforge/plantuml/graph/EntityImageComponent.java new file mode 100644 index 000000000..68c46fdce --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageComponent.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4959 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +class EntityImageComponent extends AbstractEntityImage { + + final private TextBlock name; + private final float thickness = (float) 1.6; + + public EntityImageComponent(Entity entity) { + super(entity); + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D nameDim = name.calculateDimension(stringBounder); + return Dimension2DDouble.delta(nameDim, 20, 14); + } + + private void drawRect(Graphics2D g2d, double x, double y, double width, double height) { + g2d.setStroke(new BasicStroke(thickness)); + final Shape head = new Rectangle2D.Double(x, y, width, height); + g2d.setColor(getYellow()); + g2d.fill(head); + g2d.setColor(getRed()); + g2d.draw(head); + + g2d.setStroke(new BasicStroke()); + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + final Dimension2D nameDim = name.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + + drawRect(g2d, 6, 0, dimTotal.getWidth(), dimTotal.getHeight()); + drawRect(g2d, 0, 7, 12, 6); + drawRect(g2d, 0, dimTotal.getHeight() - 7 - 6, 12, 6); + + g2d.setColor(Color.BLACK); + name.drawTOBEREMOVED(g2d, 6 + (dimTotal.getWidth() - nameDim.getWidth()) / 2, + (dimTotal.getHeight() - nameDim.getHeight()) / 2); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageDefault.java b/src/net/sourceforge/plantuml/graph/EntityImageDefault.java new file mode 100644 index 000000000..3c8456114 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageDefault.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.Arrays; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +class EntityImageDefault extends AbstractEntityImage { + + final private TextBlock textBlock; + + public EntityImageDefault(Entity entity) { + super(entity); + this.textBlock = TextBlockUtils.create(Arrays.asList(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D dim = textBlock.calculateDimension(stringBounder); + return new Dimension2DDouble(dim.getWidth(), dim.getHeight()); + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dim = textBlock.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + final int width = (int) dim.getWidth(); + final int height = (int) dim.getHeight(); + g2d.setColor(Color.BLACK); + g2d.drawRect(0, 0, width, height); + textBlock.drawTOBEREMOVED(g2d, 0, 0); + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageFactory.java b/src/net/sourceforge/plantuml/graph/EntityImageFactory.java new file mode 100644 index 000000000..6c5174a94 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageFactory.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.graph; + +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; + +public class EntityImageFactory { + + public AbstractEntityImage createEntityImage(Entity entity) { + if (entity.getType() == EntityType.CLASS || entity.getType() == EntityType.ABSTRACT_CLASS + || entity.getType() == EntityType.INTERFACE || entity.getType() == EntityType.ENUM) { + return new EntityImageClass(entity); + } + if (entity.getType() == EntityType.ACTIVITY) { + return new EntityImageActivity(entity); + } + if (entity.getType() == EntityType.NOTE) { + return new EntityImageNote(entity); + } + if (entity.getType() == EntityType.POINT_FOR_ASSOCIATION) { + return new EntityImageActivityCircle(entity, 4, 4); + } + if (entity.getType() == EntityType.CIRCLE_START) { + return new EntityImageActivityCircle(entity, 18, 18); + } + if (entity.getType() == EntityType.CIRCLE_END) { + return new EntityImageActivityCircle(entity, 18, 11); + } + if (entity.getType() == EntityType.BRANCH) { + return new EntityImageActivityBranch(entity); + } + if (entity.getType() == EntityType.SYNCHRO_BAR) { + return new EntityImageActivityBar(entity); + } + if (entity.getType() == EntityType.USECASE) { + return new EntityImageUsecase(entity); + } + if (entity.getType() == EntityType.ACTOR) { + return new EntityImageActor(entity); + } + if (entity.getType() == EntityType.CIRCLE_INTERFACE) { + return new EntityImageCircleInterface(entity); + } + if (entity.getType() == EntityType.COMPONENT) { + return new EntityImageComponent(entity); + } + return new EntityImageDefault(entity); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageNote.java b/src/net/sourceforge/plantuml/graph/EntityImageNote.java new file mode 100644 index 000000000..628c3d758 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageNote.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4959 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +class EntityImageNote extends AbstractEntityImage { + + final private TextBlock text; + + private final int xMargin = 10; + private final int yMargin = 10; + + public EntityImageNote(Entity entity) { + super(entity); + this.text = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D dim = text.calculateDimension(stringBounder); + return Dimension2DDouble.delta(dim, 2 * xMargin, 2 * yMargin); + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + + final int width = (int) dimTotal.getWidth(); + final int height = (int) dimTotal.getHeight(); + + final Polygon p = new Polygon(); + p.addPoint(0, 0); + p.addPoint(width - xMargin, 0); + p.addPoint(width, yMargin); + p.addPoint(width, height); + p.addPoint(0, height); + + g2d.setColor(getYellowNote()); + g2d.fill(p); + + g2d.setColor(getRed()); + g2d.draw(p); + g2d.drawLine(width - xMargin, 0, width - xMargin, yMargin); + g2d.drawLine(width - xMargin, yMargin, width, yMargin); + + g2d.setColor(Color.BLACK); + text.drawTOBEREMOVED(g2d, xMargin, yMargin); + + } +} diff --git a/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java b/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java new file mode 100644 index 000000000..7168b9ff5 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/EntityImageUsecase.java @@ -0,0 +1,104 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Dimension2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.QuadCurve2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +class EntityImageUsecase extends AbstractEntityImage { + + final private TextBlock name; + + public EntityImageUsecase(Entity entity) { + super(entity); + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D nameDim = name.calculateDimension(stringBounder); + // final double eps = Math.sqrt(nameDim.getWidth() / + // nameDim.getHeight()); + // final double diag = Math.sqrt(nameDim.getWidth() * nameDim.getWidth() + // + nameDim.getHeight() + // * nameDim.getHeight()); + // return new Dimension2DDouble(diag * eps, diag / eps); + final double eps = 1.7; + return new Dimension2DDouble(nameDim.getWidth() * eps, nameDim.getHeight() * eps); + } + + @Override + public void draw(Graphics2D g2d) { + final Dimension2D dimTotal = getDimension(StringBounderUtils.asStringBounder(g2d)); + + // Shape ellipse = new Ellipse2D.Double(0, 0, dimTotal.getWidth(), + // dimTotal.getHeight()); + final GeneralPath ellipse = new GeneralPath(); + final double h = dimTotal.getHeight(); + final double w = dimTotal.getWidth(); + ellipse.append(new QuadCurve2D.Double(0, h / 2, 0, 0, w / 2, 0), true); + ellipse.append(new QuadCurve2D.Double(w / 2, 0, w, 0, w, h / 2), true); + ellipse.append(new QuadCurve2D.Double(w, h / 2, w, h, w / 2, h), true); + ellipse.append(new QuadCurve2D.Double(w / 2, h, 0, h, 0, h / 2), true); + g2d.setColor(getYellow()); + g2d.fill(ellipse); + + g2d.setColor(getRed()); + g2d.draw(ellipse); + + final Dimension2D nameDim = name.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + final double posx = (w - nameDim.getWidth()) / 2; + final double posy = (h - nameDim.getHeight()) / 2; + final Shape rect = new Rectangle2D.Double(posx, posy, nameDim.getWidth(), nameDim.getHeight()); + // g2d.draw(rect); + + g2d.setColor(Color.BLACK); + name.drawTOBEREMOVED(g2d, posx, posy); + } +} diff --git a/src/net/sourceforge/plantuml/graph/Galaxy4.java b/src/net/sourceforge/plantuml/graph/Galaxy4.java new file mode 100644 index 000000000..2bafad66a --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Galaxy4.java @@ -0,0 +1,92 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.geom.Point2DInt; +import net.sourceforge.plantuml.geom.PolylineBreakeable; +import net.sourceforge.plantuml.geom.SpiderWeb; + +public class Galaxy4 { + + final private Board board; + + final private Map lines = new LinkedHashMap(); + final private SpiderWeb spiderWeb; + + public Galaxy4(Board board, int widthCell, int heightCell) { + this.spiderWeb = new SpiderWeb(widthCell, heightCell); + this.board = board; + } + + public Point2DInt getMainPoint(int row, int col) { + return spiderWeb.getMainPoint(row, col); + } + + public PolylineBreakeable getPolyline(ALink link) { + return lines.get(link); + + } + + public void addLink(ALink link) { + final int rowStart = link.getNode1().getRow(); + final int rowEnd = link.getNode2().getRow(); + final int colStart = board.getCol(link.getNode1()); + final int colEnd = board.getCol(link.getNode2()); + + final PolylineBreakeable polyline = spiderWeb.addPolyline(rowStart, colStart, rowEnd, colEnd); + + Log.info("link=" + link + " polyline=" + polyline); + + if (polyline == null) { + Log.info("PENDING " + link + " " + polyline); + } else { + lines.put(link, polyline); + } + + } + + public final Board getBoard() { + return board; + } + + public final Map getLines() { + return Collections.unmodifiableMap(lines); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/GeneralPathFactory.java b/src/net/sourceforge/plantuml/graph/GeneralPathFactory.java new file mode 100644 index 000000000..bd5dac758 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/GeneralPathFactory.java @@ -0,0 +1,156 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4625 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.geom.Box; +import net.sourceforge.plantuml.geom.LineSegmentInt; +import net.sourceforge.plantuml.geom.PolylineBreakeable; + +public class GeneralPathFactory { + + private final LinkType linkType; + + public GeneralPathFactory(LinkType linkType) { + this.linkType = linkType; + } + + public Shape getLink(PolylineBreakeable polyline, Box b1, Box b2) { + final LineSegmentInt directSegment = new LineSegmentInt(b1.getCenterX(), b1.getCenterY(), b2.getCenterX(), b2 + .getCenterY()); + assert b1.intersect(directSegment).length == 1; + assert b2.intersect(directSegment).length == 1; + + // final Point2D.Double start = polyline.clipStart(b1); + // final Point2D.Double end = polyline.clipEnd(b2); + final GeneralPath generalPath = polyline.asGeneralPath(); + // addSymbol(generalPath, start, polyline.getFirst(), end, + // polyline.getLast()); + return generalPath; + + } + + private void addSymbol(GeneralPath generalPath, Point2D.Double firstPoint, LineSegmentInt firstSeg, + Point2D.Double lastPoint, LineSegmentInt lastSeg) { +// if (linkType.equals(LinkType.AGREGATION) || linkType.equals(LinkType.COMPOSITION)) { +// addSymbolDiamond(generalPath, lastPoint, lastSeg); +// } else if (linkType.equals(LinkType.AGREGATION_INV) || linkType.equals(LinkType.COMPOSITION_INV)) { +// addSymbolDiamondInv(generalPath, firstPoint, firstSeg); +// } else if (linkType.equals(LinkType.NAVASSOC) || linkType.equals(LinkType.NAVASSOC_DASHED)) { +// addSymbolNavasoc(generalPath, lastPoint, lastSeg); +// } else if (linkType.equals(LinkType.NAVASSOC_INV) || linkType.equals(LinkType.NAVASSOC_DASHED_INV)) { +// addSymbolNavasocInv(generalPath, firstPoint, firstSeg); +// } else if (linkType.equals(LinkType.EXTENDS_INV) || linkType.equals(LinkType.IMPLEMENTS_INV)) { +// addSymbolExtends(generalPath, firstPoint, firstSeg); +// } else if (linkType.equals(LinkType.EXTENDS) || linkType.equals(LinkType.IMPLEMENTS)) { +// addSymbolExtendsInv(generalPath, lastPoint, lastSeg); +// } else { +// assert linkType.equals(LinkType.ASSOCIED) || linkType.equals(LinkType.ASSOCIED_DASHED); +// } + } + + private void addSymbolDiamond(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg) { + final Polygon arrow = new Polygon(); + arrow.addPoint(0, 0); + arrow.addPoint(-10, 6); + arrow.addPoint(-20, 0); + arrow.addPoint(-10, -6); + + appendAndRotate(generalPath, point, seg, arrow); + } + + private void addSymbolDiamondInv(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg) { + final Polygon arrow = new Polygon(); + arrow.addPoint(0, 0); + arrow.addPoint(10, 6); + arrow.addPoint(20, 0); + arrow.addPoint(10, -6); + + appendAndRotate(generalPath, point, seg, arrow); + } + + private void addSymbolNavasocInv(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg) { + final Polygon arrow = new Polygon(); + arrow.addPoint(0, 0); + arrow.addPoint(13, -8); + arrow.addPoint(6, 0); + arrow.addPoint(13, 8); + + appendAndRotate(generalPath, point, seg, arrow); + } + + private void addSymbolNavasoc(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg) { + final Polygon arrow = new Polygon(); + arrow.addPoint(0, 0); + arrow.addPoint(-13, -8); + arrow.addPoint(-6, 0); + arrow.addPoint(-13, 8); + + appendAndRotate(generalPath, point, seg, arrow); + } + + private void addSymbolExtends(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg) { + final Polygon arrow = new Polygon(); + arrow.addPoint(0, 0); + arrow.addPoint(25, 7); + arrow.addPoint(25, -7); + + appendAndRotate(generalPath, point, seg, arrow); + } + + private void addSymbolExtendsInv(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg) { + final Polygon arrow = new Polygon(); + arrow.addPoint(0, 0); + arrow.addPoint(-25, 7); + arrow.addPoint(-25, -7); + + appendAndRotate(generalPath, point, seg, arrow); + } + + private void appendAndRotate(GeneralPath generalPath, Point2D.Double point, LineSegmentInt seg, final Shape shape) { + final AffineTransform at = AffineTransform.getTranslateInstance(point.x, point.y); + final double theta = seg.getAngle(); + at.rotate(theta); + + final Shape r = at.createTransformedShape(shape); + generalPath.append(r, false); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Graph1.java b/src/net/sourceforge/plantuml/graph/Graph1.java new file mode 100644 index 000000000..3a9859374 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Graph1.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +public class Graph1 { + + private final Board board; + private final int widthCell = 40; + private final int heightCell = 40; + + public Graph1(Board board) { + this.board = board; + } + + public BufferedImage createBufferedImage() { + final BufferedImage im = new BufferedImage(widthCell * 15, heightCell * 15, BufferedImage.TYPE_INT_RGB); + final Graphics2D g2d = im.createGraphics(); + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, im.getWidth(), im.getHeight()); + + g2d.setColor(Color.BLACK); + for (ANode n : board.getNodes()) { + final int x = board.getCol(n) * widthCell; + final int y = n.getRow() * heightCell; + g2d.drawString(n.getCode(), x + 5, y + heightCell / 2 - 5); + g2d.drawOval(x, y, widthCell / 2, heightCell / 2); + } + + for (ALink link : board.getLinks()) { + final ANode n1 = link.getNode1(); + final ANode n2 = link.getNode2(); + final int x1 = 10 + board.getCol(n1) * widthCell; + final int y1 = 10 + n1.getRow() * heightCell; + final int x2 = 10 + board.getCol(n2) * widthCell; + final int y2 = 10 + n2.getRow() * heightCell; + g2d.drawLine(x1, y1, x2, y2); + + } + + return im; + + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Graph2.java b/src/net/sourceforge/plantuml/graph/Graph2.java new file mode 100644 index 000000000..32f2c05f7 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Graph2.java @@ -0,0 +1,99 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graphic.StringBounderUtils; + +public class Graph2 { + + final private static Graphics2D dummyGraphics2D; + + private final Elastane elastane; + private int widthCell; + private int heightCell; + + static { + final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); + dummyGraphics2D = builder.getGraphics2D(); + } + + public Graph2(Board board) { + board.normalize(); + + for (ANode n : board.getNodes()) { + final Dimension2D dim = images(n).getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)); + widthCell = Math.max(widthCell, (int) dim.getWidth()); + heightCell = Math.max(heightCell, (int) dim.getHeight()); + } + final Galaxy4 galaxy = new Galaxy4(board, widthCell, heightCell); + elastane = new Elastane(galaxy); + + for (ANode n : board.getNodes()) { + final Dimension2D dim = images(n).getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)); + elastane.addBox(n, (int) dim.getWidth(), (int) dim.getHeight()); + } + + final List links = new ArrayList(board.getLinks()); + Collections.sort(links, board.getLinkComparator()); + for (ALink link : links) { + galaxy.addLink(link); + } + + elastane.init(); + + } + + private AbstractEntityImage images(ANode n) { + return new EntityImageFactory().createEntityImage(((Entity) n.getUserData())); + } + + public Dimension2D getDimension() { + return elastane.getDimension(); + + } + + public void draw(final Graphics2D g2d) { + elastane.draw(g2d); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Graph3.java b/src/net/sourceforge/plantuml/graph/Graph3.java new file mode 100644 index 000000000..908bbab6f --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Graph3.java @@ -0,0 +1,480 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.geom.Line2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.geom.InflationTransform; +import net.sourceforge.plantuml.geom.Kingdom; +import net.sourceforge.plantuml.geom.LineSegmentInt; +import net.sourceforge.plantuml.geom.Point2DInt; +import net.sourceforge.plantuml.geom.Pointable; +import net.sourceforge.plantuml.geom.Polyline; +import net.sourceforge.plantuml.geom.PolylineImpl; +import net.sourceforge.plantuml.geom.XMoveable; +import net.sourceforge.plantuml.geom.kinetic.Frame; +import net.sourceforge.plantuml.geom.kinetic.Path; +import net.sourceforge.plantuml.geom.kinetic.Point2DCharge; +import net.sourceforge.plantuml.geom.kinetic.World; +import net.sourceforge.plantuml.graphic.StringBounderUtils; + +public class Graph3 { + + final private static Graphics2D dummyGraphics2D; + + private final int spaceWidth = 40; + private final int spaceHeight = 40; + private final int minDistBetweenPoint = 20; + + // private final int boxWidth = 20; + // private final int boxHeight = 20; + + private final double margin = 30; + private final Board board; + private final List polylines = new ArrayList(); + private final Map nodePoints = new LinkedHashMap(); + + private int maxRow; + private int maxCol; + + static { + final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); + dummyGraphics2D = builder.getGraphics2D(); + } + + class ANodePoint implements Pointable, XMoveable { + final private ANode node; + private int deltaX = 0; + private int deltaY = 0; + + public ANodePoint(ANode node) { + this.node = node; + } + + public Point2DInt getPosition() { + return new Point2DInt(board.getCol(node) * spaceWidth + deltaX, node.getRow() * spaceHeight + deltaY); + } + + public void moveX(int delta) { + this.deltaX += delta; + } + + public void moveY(int delta) { + this.deltaY += delta; + } + + public ANode getNode() { + return node; + } + + } + + private Collection convertANodeSet(Set nodesSet) { + final Collection result = new HashSet(); + for (ANode n : nodesSet) { + assert nodePoints.get(n) != null; + result.add(nodePoints.get(n)); + } + return result; + } + + private int addedWidth = 0; + private int addedHeight = 0; + + public Graph3(Board board) { + board.normalize(); + this.board = board; + for (ANode n : board.getNodes()) { + maxRow = Math.max(maxRow, n.getRow()); + maxCol = Math.max(maxCol, board.getCol(n)); + } + for (ANode n : board.getNodes()) { + nodePoints.put(n, new ANodePoint(n)); + } + + // for (ALink link : board.getLinks()) { + // final Pointable pp1 = nodePoints.get(link.getNode1()); + // final Pointable pp2 = nodePoints.get(link.getNode2()); + // polylines.add(new PolylineImpl(pp1, pp2)); + // } + // manyPasses(board); + // polylines.clear(); + + computePolylines(board); + + final InflationTransform inflationTransform = new InflationTransform(); + for (ANodePoint nodePoint : nodePoints.values()) { + final Point2DInt p = nodePoint.getPosition(); + final AbstractEntityImage image = getImage(nodePoint.getNode()); + + int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getWidth(); + int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getHeight(); + if (widthCell % 2 == 1) { + widthCell++; + } + if (heightCell % 2 == 1) { + heightCell++; + } + + inflationTransform.addInflationX(p.getXint(), widthCell); + addedWidth += widthCell; + inflationTransform.addInflationY(p.getYint(), heightCell); + addedHeight += heightCell; + } + + for (PolylineImpl p : polylines) { + p.inflate(inflationTransform); + } + + for (ANodePoint nodePoint : nodePoints.values()) { + final Point2DInt pos = nodePoint.getPosition(); + final Point2DInt pos2 = inflationTransform.inflatePoint2DInt(pos); + nodePoint.moveX(pos2.getXint() - pos.getXint()); + nodePoint.moveY(pos2.getYint() - pos.getYint()); + } + + // Kinematic + for (ANodePoint point : nodePoints.values()) { + final double x = point.getPosition().getX(); + final double y = point.getPosition().getY(); + final Dimension2D dim = getImage(point.getNode()).getDimension( + StringBounderUtils.asStringBounder(dummyGraphics2D)); + final Frame frame = new Frame(x, y, (int) dim.getWidth(), (int) dim.getHeight()); + frames.put(point, frame); + world.addFrame(frame); + } + + for (PolylineImpl polyline : polylines) { + final Frame f1 = frames.get(polyline.getStart()); + final Frame f2 = frames.get(polyline.getEnd()); + final Path path = new Path(f1, f2); + for (Point2DInt pt : polyline.getIntermediates()) { + path.addIntermediate(new Point2DCharge(pt.getX(), pt.getY())); + } + world.addPath(path); + } + + world.renderContinue(); + Log.info("Starting moving"); + final long start = System.currentTimeMillis(); + final int limit = 100; + for (int i = 0; i < limit; i++) { + Log.info("i=" + i); + final double move = world.onePass(); + if (move < 1) { + Log.info("i=" + i + " " + move); + // break; + } + if (i == limit - 1) { + Log.info("Aborting"); + } + } + final long duration = System.currentTimeMillis() - start; + Log.info("Ending moving (" + duration + " ms)"); + + } + + private final World world = new World(); + private final Map frames = new LinkedHashMap(); + + private void computePolylines(Board board) { + final Collection latter = new ArrayList(); + final Kingdom kingdom = new Kingdom(); + final List links = new ArrayList(board.getLinks()); + Collections.sort(links, board.getLinkComparator()); + for (ALink link : links) { + final Pointable pp1 = nodePoints.get(link.getNode1()); + final Pointable pp2 = nodePoints.get(link.getNode2()); + if (kingdom.isSimpleSegmentPossible(pp1.getPosition(), pp2.getPosition())) { + System.err.println("OK for " + link); + kingdom.addDirectLink(pp1.getPosition(), pp2.getPosition()); + polylines.add(new PolylineImpl(pp1, pp2)); + } else { + System.err.println("Latter for " + link); + latter.add(link); + } + } + + System.err.println("latters=" + latter.size()); + for (ALink link : latter) { + System.err.println("Alatter=" + link); + } + for (ALink link : latter) { + System.err.println("Blatter=" + link); + final Pointable pp1 = nodePoints.get(link.getNode1()); + final Pointable pp2 = nodePoints.get(link.getNode2()); + polylines.add((PolylineImpl) kingdom.getPath(pp1, pp2)); + } + } + + private void manyPasses(Board board) { + final Collection> xmoveableGroups = getXMoveables(board); + + System.err.println("COST_INIT=" + getCost()); + for (int i = 0; i < 300; i++) { + final boolean changed = onePass(xmoveableGroups); + if (changed == false) { + break; + } + } + System.err.println("COST_FIN=" + getCost()); + } + + private Collection> getXMoveables(Board board) { + final Set> nodesGroups = new HashSet>(); + final Collection nodes = board.getNodes(); + for (ANode root : nodes) { + for (int i = 0; i < board.getLinks().size(); i++) { + final Set group = board.getConnectedNodes(root, i); + if (group.size() < nodes.size()) { + nodesGroups.add(group); + } + } + } + + final Collection> xmoveableGroups = new ArrayList>(); + for (Set nodesSet : nodesGroups) { + xmoveableGroups.add(convertANodeSet(nodesSet)); + } + return xmoveableGroups; + } + + private void moveX(Collection boxes, int delta) { + for (XMoveable b : boxes) { + b.moveX(delta); + } + } + + private static final int STEP = 1; + + private boolean onePass(Collection> subLists) { + boolean changed = false; + for (Collection toMove : subLists) { + final double initCost = getCost(); + + assert reversable(initCost, toMove); + + moveX(toMove, STEP); + if (getCost() < initCost) { + changed = true; + } else { + moveX(toMove, -STEP); + moveX(toMove, -STEP); + if (getCost() < initCost) { + changed = true; + } else { + moveX(toMove, STEP); + assert getCost() == initCost : "c1=" + getCost() + " init=" + initCost; + } + } + assert getCost() <= initCost; + + } + // System.err.println("COSTB=" + getCost()); + return changed; + } + + private boolean reversable(double initCost, Collection toMove) { + moveX(toMove, STEP); + moveX(toMove, -STEP); + assert getCost() == initCost; + moveX(toMove, STEP); + moveX(toMove, -STEP * 2); + moveX(toMove, STEP); + assert getCost() == initCost; + return true; + } + + private double getCostOld() { + if (mindistRespected() == false) { + return Double.MAX_VALUE; + } + double result = 0; + for (PolylineImpl p : polylines) { + result += getLength(p); + + for (PolylineImpl other : polylines) { + if (other == p) { + continue; + } + if (p.doesTouch(other)) { + result += getLength(other); + } + } + } + + return result; + } + + private double getCost() { + double result = 0; + for (PolylineImpl p1 : polylines) { + for (PolylineImpl p2 : polylines) { + result += getCost(p1, p2); + } + } + + final List all = new ArrayList(nodePoints.values()); + for (int i = 0; i < all.size() - 1; i++) { + for (int j = i + 1; j < all.size(); j++) { + final double len = new LineSegmentInt(all.get(i).getPosition(), all.get(j).getPosition()).getLength(); + result += minDistBetweenPoint * minDistBetweenPoint / len / len; + } + } + + return result; + } + + private double getCost(PolylineImpl p1, PolylineImpl p2) { + assert p1.nbSegments() == 1; + assert p2.nbSegments() == 1; + + final LineSegmentInt seg1 = p1.getFirst(); + final LineSegmentInt seg2 = p2.getFirst(); + + final double len1 = seg1.getLength(); + if (p1 == p2) { + return len1 / minDistBetweenPoint; + } + final double len2 = seg2.getLength(); + + // return len1 * len2 * Math.exp(-seg1.getDistance(seg2)); + return len1 * len2 / seg1.getDistance(seg2) / minDistBetweenPoint / minDistBetweenPoint; + // return len1 * len2 * Math.exp(-seg1.getDistance(seg2)) / + // minDistBetweenPoint / minDistBetweenPoint; + } + + private boolean mindistRespected() { + final List all = new ArrayList(nodePoints.values()); + for (int i = 0; i < all.size() - 1; i++) { + for (int j = i + 1; j < all.size(); j++) { + final double len = new LineSegmentInt(all.get(i).getPosition(), all.get(j).getPosition()).getLength(); + if (len <= minDistBetweenPoint) { + return false; + } + } + } + return true; + } + + private double getLength(final Polyline p) { + final double len = p.getLength(); + assert len > 0; + return Math.log(1 + len); + } + + public Dimension2D getDimension() { + final double width = spaceWidth * maxCol;// + boxWidth * (maxCol + + // 1); + final int height = spaceWidth * maxRow;// + boxHeight * (maxRow + 1); + return new Dimension2DDouble(width + 2 * margin + addedWidth, height + 2 * margin + addedHeight); + + } + + public void draw(final Graphics2D g2d) { + g2d.translate(margin, margin); + + for (Path p : world.getPaths()) { + for (Line2D seg : p.segments()) { + g2d.setColor(Color.BLUE); + g2d.draw(seg); + g2d.setColor(Color.RED); + g2d.drawOval((int) seg.getX1(), (int) seg.getY1(), 1, 1); + } + } + + g2d.setColor(Color.GREEN); + for (ANodePoint nodePoint : nodePoints.values()) { + final Frame frame = frames.get(nodePoint); + final AbstractEntityImage image = getImage(nodePoint.getNode()); + final double width = image.getDimension(StringBounderUtils.asStringBounder(g2d)).getWidth(); + final double height = image.getDimension(StringBounderUtils.asStringBounder(g2d)).getHeight(); + g2d.translate(frame.getX() - width / 2, frame.getY() - height / 2); + image.draw(g2d); + g2d.translate(-frame.getX() + width / 2, -frame.getY() + height / 2); + } + + } + + public void draw2(final Graphics2D g2d) { + g2d.translate(margin, margin); + + g2d.setColor(Color.BLUE); + for (Polyline p : polylines) { + if (p == null) { + System.err.println("Polyline NULL!!"); + continue; + } + for (LineSegmentInt seg : p.segments()) { + g2d + .drawLine(seg.getP1().getXint(), seg.getP1().getYint(), seg.getP2().getXint(), seg.getP2() + .getYint()); + } + } + + g2d.setColor(Color.GREEN); + for (ANodePoint nodePoint : nodePoints.values()) { + final Point2DInt p = nodePoint.getPosition(); + // System.err.println("p=" + p); + final AbstractEntityImage image = getImage(nodePoint.getNode()); + final int width = (int) (image.getDimension(StringBounderUtils.asStringBounder(g2d)).getWidth()); + final int height = (int) (image.getDimension(StringBounderUtils.asStringBounder(g2d)).getHeight()); + g2d.translate(p.getXint() - width / 2, p.getYint() - height / 2); + image.draw(g2d); + g2d.translate(-p.getXint() + width / 2, -p.getYint() + height / 2); + // g2d.fillOval(p.getXint() - 2, p.getYint() - 2, 5, 5); + // g2d.drawRect(p.getXint() - 4, p.getYint() - 4, 8, 8); + } + } + + private AbstractEntityImage getImage(ANode n) { + return new EntityImageFactory().createEntityImage((Entity) n.getUserData()); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Graph4.java b/src/net/sourceforge/plantuml/graph/Graph4.java new file mode 100644 index 000000000..3ce2d2bd5 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Graph4.java @@ -0,0 +1,263 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.geom.InflationTransform; +import net.sourceforge.plantuml.geom.Point2DInt; +import net.sourceforge.plantuml.geom.Pointable; +import net.sourceforge.plantuml.geom.XMoveable; +import net.sourceforge.plantuml.geom.kinetic.Frame; +import net.sourceforge.plantuml.graph2.CubicCurveFactory; +import net.sourceforge.plantuml.graph2.MyCurve; +import net.sourceforge.plantuml.graph2.RectanglesCollection; +import net.sourceforge.plantuml.graphic.StringBounderUtils; + +public class Graph4 { + + final private static Graphics2D dummyGraphics2D; + + private final int spaceWidth = 40; + private final int spaceHeight = 40; + + private final double margin = 30; + private final Board board; + + private final Map nodePoints = new LinkedHashMap(); + private final Map frames = new LinkedHashMap(); + + private int maxRow; + private int maxCol; + + private int addedWidth = 0; + private int addedHeight = 0; + + static { + final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); + dummyGraphics2D = builder.getGraphics2D(); + } + + class ANodePoint implements Pointable, XMoveable { + final private ANode node; + private int deltaX = 0; + private int deltaY = 0; + + public ANodePoint(ANode node) { + this.node = node; + } + + public Point2DInt getPosition() { + return new Point2DInt(board.getCol(node) * spaceWidth + deltaX, node.getRow() * spaceHeight + deltaY); + } + + public void moveX(int delta) { + this.deltaX += delta; + } + + public void moveY(int delta) { + this.deltaY += delta; + } + + public ANode getNode() { + return node; + } + + } + + public Graph4(Board board) { + board.normalize(); + this.board = board; + for (ANode n : board.getNodes()) { + maxRow = Math.max(maxRow, n.getRow()); + maxCol = Math.max(maxCol, board.getCol(n)); + } + for (ANode n : board.getNodes()) { + nodePoints.put(n, new ANodePoint(n)); + } + + final InflationTransform inflationTransform = new InflationTransform(); + for (ANodePoint nodePoint : nodePoints.values()) { + final Point2DInt p = nodePoint.getPosition(); + final AbstractEntityImage image = getImage(nodePoint.getNode()); + + int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getWidth(); + int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)).getHeight(); + if (widthCell % 2 == 1) { + widthCell++; + } + if (heightCell % 2 == 1) { + heightCell++; + } + + inflationTransform.addInflationX(p.getXint(), widthCell); + addedWidth += widthCell; + inflationTransform.addInflationY(p.getYint(), heightCell); + addedHeight += heightCell; + } + + for (ANodePoint nodePoint : nodePoints.values()) { + final Point2DInt pos = nodePoint.getPosition(); + final Point2DInt pos2 = inflationTransform.inflatePoint2DInt(pos); + nodePoint.moveX(pos2.getXint() - pos.getXint()); + nodePoint.moveY(pos2.getYint() - pos.getYint()); + } + + // Kinematic + for (ANodePoint point : nodePoints.values()) { + final double x = point.getPosition().getX(); + final double y = point.getPosition().getY(); + final Dimension2D dim = getImage(point.getNode()).getDimension( + StringBounderUtils.asStringBounder(dummyGraphics2D)); + final int width = (int) dim.getWidth(); + final int height = (int) dim.getHeight(); + final Frame frame = new Frame(x - width / 2, y - height / 2, width, height); + frames.put(point, frame); + } + + } + + public Dimension2D getDimension() { + final double width = spaceWidth * maxCol; + final int height = spaceWidth * maxRow; + return new Dimension2DDouble(width + 2 * margin + addedWidth, height + 2 * margin + addedHeight); + + } + + private final List alreadyCurve = new ArrayList(); + + public void draw(final Graphics2D g2d) { + g2d.translate(margin, margin); + + g2d.setColor(Color.BLUE); + + final long start = System.currentTimeMillis(); + alreadyCurve.clear(); + for (ALink link : getSortedLinks()) { + final ANodePoint p1 = nodePoints.get(link.getNode1()); + final ANodePoint p2 = nodePoints.get(link.getNode2()); + final RectanglesCollection forbidden = getForbidden(link); + if (forbidden.size() != nodePoints.size() - 2) { + throw new IllegalStateException(); + } + final MyCurve line = getCurveLink(p1, p2, forbidden); + alreadyCurve.add(line); + line.draw(g2d); + } + final long TPS5 = System.currentTimeMillis() - start; + System.err.println("TPS5 = " + TPS5); + + g2d.setColor(Color.GREEN); + for (ANodePoint nodePoint : nodePoints.values()) { + final Frame frame = frames.get(nodePoint); + final AbstractEntityImage image = getImage(nodePoint.getNode()); + g2d.translate(frame.getX(), frame.getY()); + image.draw(g2d); + g2d.translate(-frame.getX(), -frame.getY()); + } + + } + + private List getSortedLinks() { + final Map lengths = new HashMap(); + for (ALink link : board.getLinks()) { + final ANodePoint p1 = nodePoints.get(link.getNode1()); + final ANodePoint p2 = nodePoints.get(link.getNode2()); + lengths.put(link, p1.getPosition().distance(p2.getPosition())); + } + final List all = new ArrayList(lengths.keySet()); + Collections.sort(all, new Comparator() { + public int compare(ALink l1, ALink l2) { + final double diff = lengths.get(l1) - lengths.get(l2); + return (int) Math.signum(diff); + } + }); + return all; + } + + private MyCurve getCurveLink(final ANodePoint p1, final ANodePoint p2, RectanglesCollection forbidden) { + final int x1 = p1.getPosition().getXint(); + final int y1 = p1.getPosition().getYint(); + final int x2 = p2.getPosition().getXint(); + final int y2 = p2.getPosition().getYint(); + final CubicCurve2D.Double curve = new CubicCurve2D.Double(x1, y1, x1, y1, x2, y2, x2, y2); + final MyCurve result = new MyCurve(curve); + if (result.intersects(forbidden) || result.intersects(alreadyCurve)) { + final CubicCurveFactory factory = new CubicCurveFactory(p1.getPosition(), p2.getPosition()); + for (Rectangle2D.Double r : forbidden) { + factory.addForbidden(r); + } + for (MyCurve c : alreadyCurve) { + factory.addForbidden(c); + } + return factory.getCubicCurve2D(); + + } + return result; + } + + private RectanglesCollection getForbidden(ALink link) { + final RectanglesCollection result = new RectanglesCollection(); + for (Map.Entry entry : nodePoints.entrySet()) { + final ANode node = entry.getKey(); + if (link.getNode1().equals(node) || link.getNode2().equals(node)) { + continue; + } + final ANodePoint nodePoints = entry.getValue(); + final Frame frame = frames.get(nodePoints); + result.add(new Rectangle2D.Double(frame.getX(), frame.getY(), frame.getWidth(), frame.getHeight())); + } + + return result; + } + + private AbstractEntityImage getImage(ANode n) { + return new EntityImageFactory().createEntityImage((Entity) n.getUserData()); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Graph5.java b/src/net/sourceforge/plantuml/graph/Graph5.java new file mode 100644 index 000000000..ddc4a7eeb --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Graph5.java @@ -0,0 +1,189 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.graph2.IInflationTransform; +import net.sourceforge.plantuml.graph2.InflationTransform2; +import net.sourceforge.plantuml.graph2.Plan; +import net.sourceforge.plantuml.graph2.Polyline2; +import net.sourceforge.plantuml.graphic.StringBounderUtils; + +public class Graph5 { + + final private static Graphics2D dummyGraphics2D; + + private final int spaceWidth = 40; + private final int spaceHeight = 40; + + private final double margin = 20; + private final Board board; + + private int maxRow; + private int maxCol; + + private final Plan plan = new Plan(); + private final IInflationTransform inflationTransform = new InflationTransform2(); + // private final IInflationTransform inflationTransform = new + // IdentityInflationTransform(); + + static { + final EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, Color.WHITE); + dummyGraphics2D = builder.getGraphics2D(); + } + + private AbstractEntityImage getImage(ANode n) { + return new EntityImageFactory().createEntityImage((Entity) n.getUserData()); + } + + public Graph5(Board board) { + board.normalize(); + this.board = board; + for (ANode n : board.getNodes()) { + maxRow = Math.max(maxRow, n.getRow()); + maxCol = Math.max(maxCol, board.getCol(n)); + final Point2D.Double pos = getPosition(n); + plan.addPoint2D(pos); + // System.err.println("n=" + n + " pos=" + pos); + } + for (ANode n : board.getNodes()) { + final AbstractEntityImage image = getImage(n); + final Point2D.Double pos = getPosition(n); + final int widthCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)) + .getWidth() + 20; + final int heightCell = (int) image.getDimension(StringBounderUtils.asStringBounder(dummyGraphics2D)) + .getHeight() + 20; + inflationTransform.addInflationX(pos.getX(), widthCell); + inflationTransform.addInflationY(pos.getY(), heightCell); + } + + // System.err.println("inflationTransform=" + inflationTransform); + + } + + public Point2D.Double getPosition(ANode node) { + return new Point2D.Double(board.getCol(node) * spaceWidth, node.getRow() * spaceHeight); + } + + public Dimension2D getDimension() { + final double width = spaceWidth * maxCol; + final int height = spaceWidth * maxRow; + return new Dimension2DDouble(width + 2 * margin + inflationTransform.getTotalInflationX(), height + 2 * margin + + inflationTransform.getTotalInflationY()); + + } + + public void draw(final Graphics2D g2d) { + g2d.translate(margin, margin); + g2d.setColor(Color.BLUE); + + for (ALink link : getSortedLinks()) { + final Point2D start = getPosition(link.getNode1()); + final Point2D end = getPosition(link.getNode2()); + + final List lines = buildPath(start, end); + final Polyline2 polyline = buildPolyline(start, end, lines); + polyline.draw(g2d); + } + + for (ANode n : board.getNodes()) { + final AbstractEntityImage image = getImage(n); + Point2D pos = getPosition(n); + pos = inflationTransform.inflatePoint2D(pos); + final double x = pos.getX() - image.getDimension(StringBounderUtils.asStringBounder(g2d)).getWidth() / 2; + final double y = pos.getY() - image.getDimension(StringBounderUtils.asStringBounder(g2d)).getHeight() / 2; + g2d.translate(x, y); + image.draw(g2d); + g2d.translate(-x, -y); + } + + } + + private Polyline2 buildPolyline(final Point2D start, final Point2D end, final List lines) { + final Polyline2 polyline = new Polyline2(inflationTransform.inflatePoint2D(start), inflationTransform + .inflatePoint2D(end)); + final List list = inflationTransform.inflate(lines); + for (Line2D.Double l1 : list) { + polyline.addLine(l1); + } + return polyline; + } + + private List buildPath(final Point2D start, final Point2D end) { + Point2D current = start; + final List interm = plan.getIntermediatePoints(start, end); + final List lines = new ArrayList(); + for (final Point2D.Double inter : interm) { + plan.addPoint2D(inter); + lines.add(new Line2D.Double(current, inter)); + plan.createLink(current, inter); + current = inter; + } + lines.add(new Line2D.Double(current, end)); + plan.createLink(current, end); + return lines; + } + + private List getSortedLinks() { + final Map lengths = new LinkedHashMap(); + for (ALink link : board.getLinks()) { + final Point2D.Double p1 = getPosition(link.getNode1()); + final Point2D.Double p2 = getPosition(link.getNode2()); + lengths.put(link, p1.distance(p2)); + } + final List all = new ArrayList(lengths.keySet()); + Collections.sort(all, new Comparator() { + public int compare(ALink l1, ALink l2) { + final double diff = lengths.get(l1) - lengths.get(l2); + return (int) Math.signum(diff); + } + }); + return all; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Heap.java b/src/net/sourceforge/plantuml/graph/Heap.java new file mode 100644 index 000000000..ba440a372 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Heap.java @@ -0,0 +1,240 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class Heap { + + private final Map nodes = new LinkedHashMap(); + private final Map> directChildren = new LinkedHashMap>(); + private final List links = new ArrayList(); + + public boolean isEmpty() { + if (links.isEmpty()) { + assert nodes.isEmpty(); + assert directChildren.isEmpty(); + return true; + } + return false; + } + + public void importing(ANode under, ANode otherRoot, Heap otherHeap, int diffHeight, Object userData) { + assert this.directChildren.keySet().contains(under); + assert this.nodes.values().contains(under); + assert otherHeap.nodes.values().contains(otherRoot); + assert otherHeap.directChildren.keySet().contains(otherRoot); + assert this.nodes.values().contains(otherRoot) == false; + assert this.directChildren.keySet().contains(otherRoot) == false; + assert otherHeap.directChildren.keySet().contains(under) == false; + final int oldSize = this.nodes.size(); + assert oldSize == this.directChildren.size(); + this.nodes.putAll(otherHeap.nodes); + this.directChildren.putAll(otherHeap.directChildren); + final ALinkImpl link = new ALinkImpl(under, otherRoot, diffHeight, userData); + this.links.add(link); + this.links.addAll(otherHeap.links); + assert oldSize + otherHeap.nodes.size() == this.nodes.size(); + assert oldSize + otherHeap.directChildren.size() == this.directChildren.size(); + + addUnderMe(under, otherRoot, link); + } + + public void computeRows() { + for (ANode n : nodes.values()) { + n.setRow(Integer.MIN_VALUE); + } + nodes.values().iterator().next().setRow(0); + boolean changed; + do { + onePass(); + changed = false; + for (ANode n : nodes.values()) { + if (n.getRow() != Integer.MIN_VALUE) { + continue; + } + final Map.Entry smallestRowOfChildren = getSmallestRowOfChildren(n); + if (smallestRowOfChildren != null) { + n.setRow(getStartingRow(smallestRowOfChildren)); + } + changed = true; + } + } while (changed); + + minToZero(); + } + + private int getStartingRow(Map.Entry ent) { + assert ent.getValue().getNode2() == ent.getKey(); + return ent.getValue().getNode2().getRow() - ent.getValue().getDiffHeight(); + } + + private void minToZero() { + int min = Integer.MAX_VALUE; + for (ANode n : nodes.values()) { + min = Math.min(min, n.getRow()); + } + if (min == Integer.MIN_VALUE) { + throw new IllegalStateException(); + } + if (min != 0) { + for (ANode n : nodes.values()) { + n.setRow(n.getRow() - min); + } + } + + } + + private Map.Entry getSmallestRowOfChildren(ANode n) { + assert n.getRow() == Integer.MIN_VALUE; + Map.Entry result = null; + for (Map.Entry ent : directChildren.get(n).entrySet()) { + final ANode child = ent.getKey(); + if (child.getRow() == Integer.MIN_VALUE) { + continue; + } + if (result == null || getStartingRow(ent) < getStartingRow(result)) { + result = ent; + } + } + // assert result != null; + return result; + } + + private void onePass() { + boolean changed; + do { + changed = false; + for (ANode n : nodes.values()) { + final int row = n.getRow(); + if (row == Integer.MIN_VALUE) { + continue; + } + for (Map.Entry ent : directChildren.get(n).entrySet()) { + final ANode child = ent.getKey(); + final int diffHeight = ent.getValue().getDiffHeight(); + if (child.getRow() == Integer.MIN_VALUE || child.getRow() < row + diffHeight) { + child.setRow(row + diffHeight); + changed = true; + } + } + } + } while (changed); + } + + private ANode getNode(String code) { + ANode result = nodes.get(code); + if (result == null) { + result = createNewNode(code); + } + return result; + } + + private ANode createNewNode(String code) { + final ANode result = new ANodeImpl(code); + directChildren.put(result, new LinkedHashMap()); + nodes.put(code, result); + assert directChildren.size() == nodes.size(); + return result; + } + + public ANode getExistingNode(String code) { + return nodes.get(code); + } + + public List getLinks() { + return Collections.unmodifiableList(links); + } + + public List getNodes() { + return Collections.unmodifiableList(new ArrayList(nodes.values())); + } + + HashSet getAllChildren(ANode n) { + final HashSet result = new HashSet(directChildren.get(n).keySet()); + int size = 0; + do { + size = result.size(); + for (ANode other : new HashSet(result)) { + result.addAll(getAllChildren(other)); + } + } while (result.size() != size); + return result; + } + + public void addLink(String stringLink, int diffHeight, Object userData) { + final LinkString l = new LinkString(stringLink); + final ANode n1 = getNode(l.getNode1()); + final ANode n2 = getNode(l.getNode2()); + if (n1 == n2) { + return; + } + final ALinkImpl link = new ALinkImpl(n1, n2, diffHeight, userData); + links.add(link); + + if (getAllChildren(n2).contains(n1)) { + addUnderMe(n2, n1, link); + } else { + addUnderMe(n1, n2, link); + } + } + + public ANode addNode(String code) { + if (nodes.containsKey(code)) { + throw new IllegalArgumentException(); + } + return createNewNode(code); + } + + private void addUnderMe(final ANode n1, final ANode n2, final ALinkImpl link) { + assert getAllChildren(n2).contains(n1) == false; + directChildren.get(n1).put(n2, link); + assert getAllChildren(n1).contains(n2); + assert getAllChildren(n2).contains(n1) == false; + } + + public int getRowMax() { + int max = Integer.MIN_VALUE; + for (ANode n : nodes.values()) { + max = Math.max(max, n.getRow()); + } + return max; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/KenavoCostComputer.java b/src/net/sourceforge/plantuml/graph/KenavoCostComputer.java new file mode 100644 index 000000000..d8a7c28e0 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/KenavoCostComputer.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import net.sourceforge.plantuml.geom.LineSegmentInt; + +public class KenavoCostComputer implements CostComputer { + + public double getCost(Board board) { + double result = 0; + for (ALink link1 : board.getLinks()) { + for (ALink link2 : board.getLinks()) { + result += getCost(board, link1, link2); + } + } + return result; + } + + LineSegmentInt getLineSegment(Board board, ALink link) { + final ANode n1 = link.getNode1(); + final ANode n2 = link.getNode2(); + return new LineSegmentInt(board.getCol(n1), n1.getRow(), board.getCol(n2), n2.getRow()); + } + + private double getCost(Board board, ALink link1, ALink link2) { + final LineSegmentInt seg1 = getLineSegment(board, link1); + final LineSegmentInt seg2 = getLineSegment(board, link2); + + final double len1 = getLength(link1, seg1, board); + final double len2 = getLength(link2, seg2, board); + + return len1 * len2 * Math.exp(-seg1.getDistance(seg2)); + } + + private double getLength(ALink link, final LineSegmentInt seg, Board board) { + double coef = 1; + if (link.getNode1().getRow() == link.getNode2().getRow() + && board.getDirection(link) != board.getInitialDirection(link)) { + coef = 1.1; + } + + return seg.getLength() * coef; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/LenghtLinkComparator.java b/src/net/sourceforge/plantuml/graph/LenghtLinkComparator.java new file mode 100644 index 000000000..a25ca123d --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/LenghtLinkComparator.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.Comparator; +import java.util.Map; + +public class LenghtLinkComparator implements Comparator { + + private final Map cols; + + public LenghtLinkComparator(Map cols) { + this.cols = cols; + } + + public int compare(ALink link1, ALink link2) { + return (int) Math.signum(getLenght(link1) - getLenght(link2)); + } + + private double getLenght(ALink link) { + final ANode n1 = link.getNode1(); + final ANode n2 = link.getNode2(); + final int deltaRow = n2.getRow() - n1.getRow(); + final int deltaCol = cols.get(n2) - cols.get(n1); + return deltaRow * deltaRow + deltaCol * deltaCol; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/LinkString.java b/src/net/sourceforge/plantuml/graph/LinkString.java new file mode 100644 index 000000000..159b2abb6 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/LinkString.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LinkString { + + final private static Pattern p = Pattern.compile("(.*)->(.*)"); + + final private String node1; + final private String node2; + + public LinkString(String desc) { + final Matcher m = p.matcher(desc); + if (m.find() == false) { + throw new IllegalArgumentException(); + } + node1 = m.group(1); + node2 = m.group(2); + + } + + public final String getNode1() { + return node1; + } + + public final String getNode2() { + return node2; + } +} diff --git a/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea.java b/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea.java new file mode 100644 index 000000000..f68aae3bc --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5386 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class MethodsOrFieldsArea { + + private final Font font; + private final List strings = new ArrayList(); + + public MethodsOrFieldsArea(List attributes, Font font) { + this.font = font; + for (Member att : attributes) { + this.strings.add(att.getDisplayWithVisibilityChar()); + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + double x = 0; + double y = 0; + for (String s : strings) { + final TextBlock bloc = createTextBlock(s); + final Dimension2D dim = bloc.calculateDimension(stringBounder); + y += dim.getHeight(); + x = Math.max(dim.getWidth(), x); + } + return new Dimension2DDouble(x, y); + } + + private TextBlock createTextBlock(String s) { + return TextBlockUtils.create(Arrays.asList(s), font, Color.BLACK, HorizontalAlignement.LEFT); + } + + public void drawTOBEREMOVED(Graphics2D g2d, double x, double y) { + for (String s : strings) { + final TextBlock bloc = createTextBlock(s); + bloc.drawTOBEREMOVED(g2d, x, y); + y += bloc.calculateDimension(StringBounderUtils.asStringBounder(g2d)).getHeight(); + } + } + + public void draw(UGraphic ug, double x, double y) { + for (String s : strings) { + final TextBlock bloc = createTextBlock(s); + bloc.drawU(ug, x, y); + y += bloc.calculateDimension(ug.getStringBounder()).getHeight(); + } + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Move.java b/src/net/sourceforge/plantuml/graph/Move.java new file mode 100644 index 000000000..d6337bb1a --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Move.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +public class Move { + + private final int row; + private final int col; + private final int delta; + + @Override + public String toString() { + return row + "." + col + "->" + row + "." + (col + delta); + } + + public Move(int row, int col, int delta) { + if (delta != 1 && delta != -1) { + throw new IllegalArgumentException(); + } + this.row = row; + this.col = col; + this.delta = delta; + } + + public int getRow() { + return row; + } + + public int getCol() { + return col; + } + + public int getNewCol() { + return col + delta; + } + + public int getDelta() { + return delta; + } + + public Move getBackMove() { + return new Move(row, col + delta, -delta); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Oven.java b/src/net/sourceforge/plantuml/graph/Oven.java new file mode 100644 index 000000000..3e3dc5960 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Oven.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.Random; + +public class Oven { + + final private double temp; + final private CostComputer costComputer; + + public Oven(double temp, CostComputer costComputer) { + this.temp = temp; + this.costComputer = costComputer; + } + + public Board longTic(int nbTic, Board board, Random rnd) { + double best = costComputer.getCost(board); + Board bestBoard = board.copy(); + for (int i = 0; i < nbTic; i++) { + final double current = tic(board, rnd); + // System.err.println("current=" + current + " best=" + best); + if (current < best) { + best = current; + bestBoard = board.copy(); + } + + } + return bestBoard; + } + + public double tic(Board board, Random rnd) { + // System.err.println("Oven::tic"); + final double costBefore = costComputer.getCost(board); + final Move move = null;// board.getRandomMove(rnd); + board.applyMove(move); + final double costAfter = costComputer.getCost(board); + final double delta = costAfter - costBefore; + // System.err.println("delta=" + delta); + if (delta <= 0) { + return costAfter; + } + assert delta > 0; + assert costAfter > costBefore; + // System.err.println("temp=" + temp); + if (temp > 0) { + final double probability = Math.exp(-delta / temp); + final double dice = rnd.nextDouble(); + // System.err.println("probability=" + probability + " dice=" + + // dice); + if (dice < probability) { + // System.err.println("We keep it"); + return costAfter; + } + } + // System.err.println("Roolback"); + board.applyMove(move.getBackMove()); + assert costBefore == costComputer.getCost(board); + return costBefore; + + } +} diff --git a/src/net/sourceforge/plantuml/graph/SimpleCostComputer.java b/src/net/sourceforge/plantuml/graph/SimpleCostComputer.java new file mode 100644 index 000000000..5b47c5f35 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/SimpleCostComputer.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +public class SimpleCostComputer implements CostComputer { + + /* + * (non-Javadoc) + * + * @see net.sourceforge.plantuml.graph.CostComputer#getCost(net.sourceforge.plantuml.graph.Board) + */ + public double getCost(Board board) { + double result = 0; + for (ALink link : board.getLinks()) { + final ANode n1 = link.getNode1(); + final ANode n2 = link.getNode2(); + final int x1 = board.getCol(n1); + final int y1 = n1.getRow(); + final int x2 = board.getCol(n2); + final int y2 = n2.getRow(); + result += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graph/SortedCollection.java b/src/net/sourceforge/plantuml/graph/SortedCollection.java new file mode 100644 index 000000000..93e645c06 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/SortedCollection.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +public interface SortedCollection> extends Iterable { + + int size(); + + void add(S entry); + + boolean contains(S entry); + +} diff --git a/src/net/sourceforge/plantuml/graph/SortedCollectionArrayList.java b/src/net/sourceforge/plantuml/graph/SortedCollectionArrayList.java new file mode 100644 index 000000000..f445be251 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/SortedCollectionArrayList.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class SortedCollectionArrayList> implements SortedCollection { + + private final List allAsList = new ArrayList(); + private final Set allAsSet = new HashSet(); + + public Iterator iterator() { + return allAsList.iterator(); + } + + public void add(S newEntry) { + final int r = Collections.binarySearch(allAsList, newEntry); + if (r >= 0) { + allAsList.add(r, newEntry); + } else { + allAsList.add(-1 - r, newEntry); + } + allAsSet.add(newEntry); + assert isSorted(); + } + + public int size() { + assert allAsSet.size() == allAsList.size(); + return allAsList.size(); + } + + List toList() { + return new ArrayList(allAsList); + } + + boolean isSorted() { + S before = null; + for (S ent : allAsList) { + if (before != null && ent.compareTo(before) < 0) { + return false; + } + before = ent; + } + return true; + } + + public boolean contains(S entry) { + return allAsSet.contains(entry); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/SortedCollectionLinked.java b/src/net/sourceforge/plantuml/graph/SortedCollectionLinked.java new file mode 100644 index 000000000..cfd3312d7 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/SortedCollectionLinked.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +public class SortedCollectionLinked> implements SortedCollection { + + private final List all = new LinkedList(); + + public Iterator iterator() { + return all.iterator(); + } + + public void add(S newEntry) { + for (final ListIterator it = all.listIterator(); it.hasNext();) { + final S cur = it.next(); + if (cur.compareTo(newEntry) >= 0) { + it.previous(); + it.add(newEntry); + assert isSorted(); + return; + } + } + all.add(newEntry); + assert isSorted(); + } + + public int size() { + return all.size(); + } + + List toList() { + return new ArrayList(all); + } + + boolean isSorted() { + S before = null; + for (S ent : all) { + if (before != null && ent.compareTo(before) < 0) { + return false; + } + before = ent; + } + return true; + } + + public boolean contains(S entry) { + return all.contains(entry); + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Zoda1.java b/src/net/sourceforge/plantuml/graph/Zoda1.java new file mode 100644 index 000000000..539d2a7a5 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Zoda1.java @@ -0,0 +1,166 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * @deprecated + * + */ +public class Zoda1 { + + private final Map nodes = new LinkedHashMap(); + private final List links = new ArrayList(); + + public ANodeImpl getNode(String code) { + ANodeImpl result = nodes.get(code); + if (result == null) { + result = new ANodeImpl(code); + nodes.put(code, result); + } + return result; + } + + public ANodeImpl getExistingNode(String code) { + return nodes.get(code); + } + + public List getLinks() { + return Collections.unmodifiableList(links); + } + + public List getNodes() { + return Collections.unmodifiableList(new ArrayList(nodes.values())); + } + + public void addLink(String link) { + final LinkString l = new LinkString(link); + final ANodeImpl n1 = getNode(l.getNode1()); + final ANodeImpl n2 = getNode(l.getNode2()); + links.add(new ALinkImpl(n1, n2, 1, null)); + } + + public void computeRows() { + getNodes().get(0).setRow(0); + + for (int i = 0; i < links.size(); i++) { + oneStep1(); + oneStep2(); + } + + removeUnplacedNodes(); + } + + private void removeUnplacedNodes() { + for (final Iterator it = nodes.values().iterator(); it.hasNext();) { + final ANodeImpl n = it.next(); + if (n.getRow() == Integer.MIN_VALUE) { + removeLinksOf(n); + it.remove(); + } + } + + } + + private void removeLinksOf(ANodeImpl n) { + for (final Iterator it = links.iterator(); it.hasNext();) { + final ALink link = it.next(); + if (link.getNode1() == n || link.getNode2() == n) { + it.remove(); + } + } + + } + + public int getRowMax() { + int max = 0; + for (ANode n : getNodes()) { + if (n.getRow() == Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + if (n.getRow() > max) { + max = n.getRow(); + } + } + return max; + } + + private void oneStep1() { + for (ALink link : links) { + final ANode n1 = link.getNode1(); + if (n1.getRow() == Integer.MIN_VALUE) { + continue; + } + final ANode n2 = link.getNode2(); + if (n2.getRow() == Integer.MIN_VALUE) { + n2.setRow(n1.getRow() + 1); + } else if (n2.getRow() < n1.getRow() + 1) { + n2.setRow(n1.getRow() + 1); + } + } + } + + private void oneStep2() { + for (ALink link : links) { + final ANode n1 = link.getNode1(); + final ANode n2 = link.getNode2(); + if (n1.getRow() == Integer.MIN_VALUE && n2.getRow() != Integer.MIN_VALUE) { + if (n2.getRow() == 0) { + allDown(); + } + final int row = n2.getRow() - 1; + if (row == -1) { + throw new UnsupportedOperationException(); + } + n1.setRow(row); + } + } + } + + private void allDown() { + for (ANodeImpl n : nodes.values()) { + if (n.getRow() != Integer.MIN_VALUE) { + n.setRow(n.getRow() + 1); + } + } + + } + +} diff --git a/src/net/sourceforge/plantuml/graph/Zoda2.java b/src/net/sourceforge/plantuml/graph/Zoda2.java new file mode 100644 index 000000000..5ee584bb1 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph/Zoda2.java @@ -0,0 +1,124 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class Zoda2 { + + private final Map heaps = new LinkedHashMap(); + + public ANode getNode(String code) { + for (ANode n : heaps.keySet()) { + if (n.getCode().equals(code)) { + return n; + } + } + return null; + } + + public ANode createAloneNode(String code) { + if (getNode(code) != null) { + throw new IllegalArgumentException(); + } + final Heap h = new Heap(); + final ANode n = h.addNode(code); + heaps.put(n, h); + return n; + } + + public List getNodes() { + return Collections.unmodifiableList(new ArrayList(heaps.keySet())); + } + + public Set getHeaps() { + return new HashSet(heaps.values()); + } + + public void addLink(String link, int diffHeight, Object userData) { + final LinkString l; + try { + l = new LinkString(link); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return; + } + final ANode n1 = getNode(l.getNode1()); + final ANode n2 = getNode(l.getNode2()); + final Heap h1 = n1 == null ? null : heaps.get(n1); + final Heap h2 = n2 == null ? null : heaps.get(n2); + assert h1 == null || h1.isEmpty() == false; + assert h2 == null || h2.isEmpty() == false; + if (h1 == null && h2 == null) { + final Heap h = new Heap(); + h.addLink(link, diffHeight, userData); + recordHeap(h); + } else if (h1 == h2) { + assert h1 != null && h2 != null; + h1.addLink(link, diffHeight, userData); + } else if (h1 == null) { + h2.addLink(link, diffHeight, userData); + recordHeap(h2); + } else if (h2 == null) { + h1.addLink(link, diffHeight, userData); + recordHeap(h1); + } else { + assert h1 != null && h2 != null; + assert h1.getNodes().contains(n1); + h1.importing(n1, n2, h2, diffHeight, userData); + recordHeap(h1); + assert heapMerged(h1, h2); + } + } + + private boolean heapMerged(final Heap destination, final Heap source) { + for (ANode n : source.getNodes()) { + assert heaps.get(n) == destination; + } + return true; + } + + private void recordHeap(final Heap h) { + for (ANode n : h.getNodes()) { + heaps.put((ANodeImpl) n, h); + } + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/CubicCurveFactory.java b/src/net/sourceforge/plantuml/graph2/CubicCurveFactory.java new file mode 100644 index 000000000..6b2d6ff1f --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/CubicCurveFactory.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class CubicCurveFactory { + + private final Point2D.Double start; + private final Point2D.Double end; + private final RectanglesCollection forbiddenRect = new RectanglesCollection(); + private final List forbiddenCurves = new ArrayList(); + + public CubicCurveFactory(Point2D start, Point2D end) { + this.start = new Point2D.Double(start.getX(), start.getY()); + this.end = new Point2D.Double(end.getX(), end.getY()); + } + + public void addForbidden(Rectangle2D.Double rect) { + forbiddenRect.add(rect); + } + + public void addForbidden(MyCurve curve) { + forbiddenCurves.add(curve); + } + + public MyCurve getCubicCurve2D() { + MyCurve result = new MyCurve(new CubicCurve2D.Double(start.getX(), start.getY(), start.getX(), start.getY(), + end.getX(), end.getY(), end.getX(), end.getY())); + if (result.intersects(forbiddenRect) || result.intersects(forbiddenCurves)) { + final Set all = new HashSet(); + all.addAll(MagicPointsFactory.get(start, end)); + for (Rectangle2D.Double rect : forbiddenRect) { + all.addAll(MagicPointsFactory.get(rect)); + } + System.err.println("s1 " + all.size()); + final long t1 = System.currentTimeMillis(); + double min = Double.MAX_VALUE; + for (Point2D.Double p1 : all) { + for (Point2D.Double p2 : all) { + final MyCurve me = new MyCurve(new CubicCurve2D.Double(start.getX(), start.getY(), p1.getX(), p1 + .getY(), p2.getX(), p2.getY(), end.getX(), end.getY())); + if (me.getLenght() < min && me.intersects(forbiddenRect) == false + && me.intersects(forbiddenCurves) == false) { + result = me; + min = me.getLenght(); + } + } + } + final long t2 = System.currentTimeMillis() - t1; + System.err.println("s2 = " + t2); + System.err.println("TPS1 = " + RectanglesCollection.TPS1); + System.err.println("TPS2 = " + RectanglesCollection.TPS2); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/Dijkstra.java b/src/net/sourceforge/plantuml/graph2/Dijkstra.java new file mode 100644 index 000000000..8d8025101 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/Dijkstra.java @@ -0,0 +1,154 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +/* + * Copyright (c) 2009 the authors listed at the following URL, and/or the + * authors of referenced articles or incorporated external code: + * http://en.literateprograms.org/Dijkstra's_algorithm_(Java)?action=history&offset=20081113161332 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Retrieved from: + * http://en.literateprograms.org/Dijkstra's_algorithm_(Java)?oldid=15444 + */ + +// http://www.google.fr/search?hl=fr&source=hp&q=A+star+java&btnG=Recherche+Google&meta=&aq=f&oq= +// http://www.edenwaith.com/products/pige/tutorials/a-star.php +import java.util.ArrayList; +import java.util.List; +import java.util.PriorityQueue; + +public class Dijkstra { + + static class Vertex implements Comparable { + private final Object data; + private final List adjacencies = new ArrayList(); + private double minDistance = Double.POSITIVE_INFINITY; + private Vertex previous; + + Vertex(Object data) { + this.data = data; + } + + public void addAdjacencies(Vertex target, double dist) { + if (target == null) { + throw new IllegalArgumentException(); + } + adjacencies.add(new Edge(target, dist)); + } + + public String toString() { + return "[ " + data.toString() + " (" + minDistance + ") ] "; + } + + public int compareTo(Vertex other) { + return Double.compare(minDistance, other.minDistance); + } + + public final Object getData() { + return data; + } + + } + + static class Edge { + private final Vertex target; + private final double weight; + + Edge(Vertex argTarget, double argWeight) { + target = argTarget; + weight = argWeight; + } + } + + private final List vertices = new ArrayList(); + + public Vertex addVertex(Object data) { + final Vertex v = new Vertex(data); + vertices.add(v); + return v; + } + + private void computePaths(Vertex source) { + source.minDistance = 0.; + final PriorityQueue vertexQueue = new PriorityQueue(); + vertexQueue.add(source); + + while (vertexQueue.isEmpty() == false) { + final Vertex u = vertexQueue.poll(); + + // Visit each edge exiting u + for (Edge e : u.adjacencies) { + final Vertex v = e.target; + final double weight = e.weight; + final double distanceThroughU = u.minDistance + weight; + if (distanceThroughU < v.minDistance) { + vertexQueue.remove(v); + + v.minDistance = distanceThroughU; + v.previous = u; + vertexQueue.add(v); + } + } + } + } + + public List getShortestPathTo(Vertex source, Vertex target) { + computePaths(source); + final List path = new ArrayList(); + for (Vertex vertex = target; vertex != null; vertex = vertex.previous) { + path.add(0, vertex); + } + + return path; + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/GeomUtils.java b/src/net/sourceforge/plantuml/graph2/GeomUtils.java new file mode 100644 index 000000000..8e0611e7d --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/GeomUtils.java @@ -0,0 +1,146 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.Graphics2D; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; + +public class GeomUtils { + + public static Point2D translate(Point2D pt, double deltaX, double deltaY) { + return new Point2D.Double(pt.getX() + deltaX, pt.getY() + deltaY); + } + + static public boolean isHorizontal(Line2D.Double seg) { + return seg.getP1().getY() == seg.getP2().getY(); + } + + static public boolean isVertical(Line2D.Double seg) { + return seg.getP1().getX() == seg.getP2().getX(); + } + + static public double getMinX(Line2D.Double seg) { + return Math.min(seg.x1, seg.x2); + } + + static public double getMaxX(Line2D.Double seg) { + return Math.max(seg.x1, seg.x2); + } + + static public double getMinY(Line2D.Double seg) { + return Math.min(seg.y1, seg.y2); + } + + static public double getMaxY(Line2D.Double seg) { + return Math.max(seg.y1, seg.y2); + } + + static public Point2D.Double getPoint2D(Line2D.Double line, double u) { + final double x = line.x1 + u * (line.x2 - line.x1); + final double y = line.y1 + u * (line.y2 - line.y1); + return new Point2D.Double(x, y); + } + + private static boolean isBetween(double value, double v1, double v2) { + if (v1 < v2) { + return value >= v1 && value <= v2; + } + assert v2 <= v1; + return value >= v2 && value <= v1; + + } + + static boolean isBetween(Point2D toTest, Point2D pos1, Point2D pos2) { + return isBetween(toTest.getX(), pos1.getX(), pos2.getX()) && isBetween(toTest.getY(), pos1.getY(), pos2.getY()); + } + + static private double getIntersectionVertical(Line2D.Double line, double xOther) { + final double coef = line.x2 - line.x1; + if (coef == 0) { + return java.lang.Double.NaN; + } + return (xOther - line.x1) / coef; + } + + static private double getIntersectionHorizontal(Line2D.Double line, double yOther) { + final double coef = line.y2 - line.y1; + if (coef == 0) { + return java.lang.Double.NaN; + } + return (yOther - line.y1) / coef; + } + + static public Point2D.Double getSegIntersection(Line2D.Double line1, Line2D.Double line2) { + final double u; + if (isVertical(line2)) { + u = getIntersectionVertical(line1, line2.getP1().getX()); + } else if (isHorizontal(line2)) { + u = getIntersectionHorizontal(line1, line2.getP1().getY()); + } else { + throw new UnsupportedOperationException(); + } + if (java.lang.Double.isNaN(u) || u < 0 || u > 1) { + return null; + } + final Point2D.Double result = getPoint2D(line1, u); + if (isBetween(result, line2.getP1(), line2.getP2())) { + return result; + } + return null; + } + + public static String toString(Line2D line) { + // return line.getP1() + "-" + line.getP2(); + return toString(line.getP1()) + "-" + toString(line.getP2()); + } + + public static String toString(Point2D pt) { + return "[" + pt.getX() + "," + pt.getY() + "]"; + } + + public static Point2D.Double getCenter(Line2D.Double l) { + final double x = (l.getX1() + l.getX2()) / 2; + final double y = (l.getY1() + l.getY2()) / 2; + return new Point2D.Double(x, y); + } + + public static void fillPoint2D(Graphics2D g2d, Point2D pt) { + final int x = (int) pt.getX() - 1; + final int y = (int) pt.getY() - 1; + g2d.fillOval(x, y, 3, 3); + + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/IInflationTransform.java b/src/net/sourceforge/plantuml/graph2/IInflationTransform.java new file mode 100644 index 000000000..428318b6d --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/IInflationTransform.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.Collection; +import java.util.List; + +public interface IInflationTransform { + + void addInflationX(double xpos, double inflation); + + void addInflationY(double ypos, double inflation); + + double getTotalInflationX(); + + double getTotalInflationY(); + + Point2D inflatePoint2D(Point2D point); + + List inflate(Collection segments); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graph2/IdentityInflationTransform.java b/src/net/sourceforge/plantuml/graph2/IdentityInflationTransform.java new file mode 100644 index 000000000..7bb8f6838 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/IdentityInflationTransform.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class IdentityInflationTransform implements IInflationTransform { + + public void addInflationX(double xpos, double inflation) { + + } + + public void addInflationY(double ypos, double inflation) { + + } + + public double getTotalInflationX() { + return 0; + } + + public double getTotalInflationY() { + return 0; + } + + public Point2D inflatePoint2D(Point2D point) { + return point; + } + + public List inflate(Collection segments) { + return new ArrayList(segments); + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graph2/InflateData2.java b/src/net/sourceforge/plantuml/graph2/InflateData2.java new file mode 100644 index 000000000..5bfb823ef --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/InflateData2.java @@ -0,0 +1,124 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +public class InflateData2 implements Comparable { + + private final double pos; + private final double inflation; + + public InflateData2(double pos, double inflation) { + this.pos = pos; + this.inflation = inflation; + } + + public final double getPos() { + return pos; + } + + public final double getInflation() { + return inflation; + } + + public int compareTo(InflateData2 other) { + return -Double.compare(this.pos, other.pos); + } + + // public Point2D inflateX(Point2D pt) { + // if (pt.getX() < pos) { + // return pt; + // } + // if (pt.getX() == pos) { + // return GeomUtils.translate(pt, inflation / 2, 0); + // } + // return GeomUtils.translate(pt, inflation, 0); + // } + // + public double inflateAt(double v) { + if (v == pos) { + return inflation / 2; + } + + if (v < pos) { + return 0; + } + return inflation; + } + + // public Line2D.Double inflateXAlpha(Line2D.Double line) { + // + // if (GeomUtils.isHorizontal(line)) { + // return new Line2D.Double(inflateX(line.getP1()), inflateX(line.getP2())); + // } + // if (line.x1 == pos && line.x2 == pos) { + // return new Line2D.Double(GeomUtils.translate(line.getP1(), inflation / 2, + // 0), GeomUtils.translate(line + // .getP2(), inflation / 2, 0)); + // } + // if (line.x1 <= pos && line.x2 <= pos) { + // return line; + // } + // if (line.x1 >= pos && line.x2 >= pos) { + // return new Line2D.Double(GeomUtils.translate(line.getP1(), inflation, 0), + // GeomUtils.translate(line.getP2(), + // inflation, 0)); + // } + // throw new UnsupportedOperationException(); + // } + // + // public Line2D.Double inflateYAlpha(Line2D.Double line) { + // if (GeomUtils.isVertical(line)) { + // return new Line2D.Double(inflateY(line.getP1()), inflateY(line.getP2())); + // } + // if (line.y1 == pos && line.y2 == pos) { + // return new Line2D.Double(GeomUtils.translate(line.getP1(), 0, inflation / + // 2), GeomUtils.translate(line + // .getP2(), 0, inflation / 2)); + // } + // if (line.y1 <= pos && line.y2 <= pos) { + // return line; + // } + // if (line.y1 >= pos && line.y2 >= pos) { + // return new Line2D.Double(GeomUtils.translate(line.getP1(), 0, inflation), + // GeomUtils.translate(line.getP2(), + // 0, inflation)); + // } + // throw new UnsupportedOperationException(); + // } + + @Override + public String toString() { + return "" + pos + " (" + inflation + ")"; + } +} diff --git a/src/net/sourceforge/plantuml/graph2/InflationTransform2.java b/src/net/sourceforge/plantuml/graph2/InflationTransform2.java new file mode 100644 index 000000000..80c83c454 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/InflationTransform2.java @@ -0,0 +1,238 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; +import java.util.SortedSet; +import java.util.TreeSet; + +class Point2DComparatorDistance implements Comparator { + + private final Point2D center; + + public Point2DComparatorDistance(Point2D center) { + this.center = center; + } + + public int compare(Point2D p1, Point2D p2) { + return Double.compare(p1.distance(center), p2.distance(center)); + } + +} + +public class InflationTransform2 implements IInflationTransform { + + private final List inflateX = new ArrayList(); + private final List inflateY = new ArrayList(); + + public void addInflationX(double xpos, double inflation) { + add(inflateX, xpos, inflation); + } + + @Override + public String toString() { + return "inflateX = " + inflateX + " inflateY = " + inflateY; + } + + public void addInflationY(double ypos, double inflation) { + add(inflateY, ypos, inflation); + } + + public double getTotalInflationX() { + return sumInflation(inflateX); + } + + public double getTotalInflationY() { + return sumInflation(inflateY); + } + + static private double sumInflation(List list) { + double result = 0; + for (InflateData2 data : list) { + result += data.getInflation(); + } + return result; + } + + static private void add(List list, double ypos, double inflation) { + for (final ListIterator it = list.listIterator(); it.hasNext();) { + final InflateData2 cur = it.next(); + if (cur.getPos() == ypos) { + it.set(new InflateData2(ypos, Math.max(inflation, cur.getInflation()))); + return; + } + } + list.add(new InflateData2(ypos, inflation)); + Collections.sort(list); + } + + Collection cutPoints(Line2D.Double original) { + + final SortedSet result = new TreeSet(new Point2DComparatorDistance(original + .getP1())); + + if (GeomUtils.isHorizontal(original) == false) { + for (InflateData2 x : inflateX) { + final Line2D.Double vertical = new Line2D.Double(x.getPos(), GeomUtils.getMinY(original), x.getPos(), + GeomUtils.getMaxY(original)); + final Point2D.Double inter = GeomUtils.getSegIntersection(original, vertical); + if (inter != null) { + result.add(inter); + } + } + } + if (GeomUtils.isVertical(original) == false) { + for (InflateData2 y : inflateY) { + final Line2D.Double horizontal = new Line2D.Double(GeomUtils.getMinX(original), y.getPos(), GeomUtils + .getMaxX(original), y.getPos()); + final Point2D.Double inter = GeomUtils.getSegIntersection(original, horizontal); + if (inter != null) { + result.add(inter); + } + } + } + return result; + } + + Collection cutSegments(Line2D.Double original) { + final List result = new ArrayList(); + Point2D.Double cur = (Point2D.Double) original.getP1(); + final Collection cutPoints = cutPoints(original); + for (Point2D.Double inter : cutPoints) { + if (cur.equals(inter)) { + continue; + } + result.add(new Line2D.Double(cur, inter)); + cur = inter; + } + if (cur.equals(original.getP2()) == false) { + result.add(new Line2D.Double(cur, original.getP2())); + } + return result; + } + + Collection cutSegments(Collection segments) { + final List result = new ArrayList(); + for (Line2D.Double seg : segments) { + result.addAll(cutSegments(seg)); + } + return result; + } + + // private Line2D.Double inflateSegment(Line2D.Double seg) { + // // if (isOnGrid(seg.getP1()) && isOnGrid(seg.getP2())) { + // // return new Line2D.Double(inflatePoint2D(seg.getP1()), + // inflatePoint2D(seg.getP2())); + // // } + // // for (InflateData2 x : inflateX) { + // // seg = x.inflateXAlpha(seg); + // // } + // // for (InflateData2 y : inflateY) { + // // seg = y.inflateYAlpha(seg); + // // } + // // return seg; + // return new Line2D.Double(inflatePoint2D(seg.getP1()), + // inflatePoint2D(seg.getP2())); + // } + + // private boolean isOnGrid(Point2D point) { + // boolean onGrid = false; + // for (InflateData2 x : inflateX) { + // if (point.getX() == x.getPos()) { + // onGrid = true; + // } + // } + // if (onGrid == false) { + // return false; + // } + // for (InflateData2 y : inflateY) { + // if (point.getY() == y.getPos()) { + // return true; + // } + // } + // return false; + // + // } + + public Point2D inflatePoint2D(Point2D point) { + return getAffineTransformAt(point).transform(point, null); + } + + AffineTransform getAffineTransformAt(Point2D point) { + double deltaX = 0; + for (InflateData2 x : inflateX) { + deltaX += x.inflateAt(point.getX()); + } + double deltaY = 0; + for (InflateData2 y : inflateY) { + deltaY += y.inflateAt(point.getY()); + } + return AffineTransform.getTranslateInstance(deltaX, deltaY); + } + + List inflateSegmentCollection(Collection segments) { + final List result = new ArrayList(); + for (Line2D.Double seg : segments) { + final AffineTransform at = getAffineTransformAt(new Point2D.Double((seg.x1 + seg.x2) / 2, + (seg.y1 + seg.y2) / 2)); + result.add(new Line2D.Double(at.transform(seg.getP1(), null), at.transform(seg.getP2(), null))); + } + return result; + } + + public List inflate(Collection segments) { + final Collection cutSegments = cutSegments(segments); + Line2D.Double last = null; + final List inflated = inflateSegmentCollection(cutSegments); + final List result = new ArrayList(); + for (Line2D.Double seg : inflated) { + if (last != null && last.getP2().equals(seg.getP1()) == false) { + result.add(new Line2D.Double(last.getP2(), seg.getP1())); + } + result.add(seg); + last = seg; + + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/MagicPointsFactory.java b/src/net/sourceforge/plantuml/graph2/MagicPointsFactory.java new file mode 100644 index 000000000..0d013b9aa --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/MagicPointsFactory.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.List; + +public class MagicPointsFactory { + + private MagicPointsFactory() { + + } + + public static List get(Rectangle2D.Double rect) { + final List result = new ArrayList(); + result.add(new Point2D.Double(rect.x - rect.width, rect.y - rect.height)); + result.add(new Point2D.Double(rect.x, rect.y - rect.height)); + result.add(new Point2D.Double(rect.x + rect.width, rect.y - rect.height)); + result.add(new Point2D.Double(rect.x + 2 * rect.width, rect.y - rect.height)); + + result.add(new Point2D.Double(rect.x - rect.width, rect.y)); + result.add(new Point2D.Double(rect.x + 2 * rect.width, rect.y)); + + result.add(new Point2D.Double(rect.x - rect.width, rect.y + rect.height)); + result.add(new Point2D.Double(rect.x + 2 * rect.width, rect.y + rect.height)); + + result.add(new Point2D.Double(rect.x - rect.width, rect.y + 2 * rect.height)); + result.add(new Point2D.Double(rect.x, rect.y + 2 * rect.height)); + result.add(new Point2D.Double(rect.x + rect.width, rect.y + 2 * rect.height)); + result.add(new Point2D.Double(rect.x + 2 * rect.width, rect.y + 2 * rect.height)); + return result; + } + + public static List get(Point2D.Double p1, Point2D.Double p2) { + final List result = new ArrayList(); + result.add(new Point2D.Double(p1.x, p2.y)); + result.add(new Point2D.Double(p2.x, p1.y)); + return result; + } +} diff --git a/src/net/sourceforge/plantuml/graph2/MagicPointsFactory2.java b/src/net/sourceforge/plantuml/graph2/MagicPointsFactory2.java new file mode 100644 index 000000000..2de346839 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/MagicPointsFactory2.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +public class MagicPointsFactory2 { + + private final Point2D.Double p1; + private final Point2D.Double p2; + + private final List result = new ArrayList(); + + public MagicPointsFactory2(Point2D.Double p1, Point2D.Double p2) { + this.p1 = p1; + this.p2 = p2; + final double dx = p2.x - p1.x; + final double dy = p2.y - p1.y; + + final int interv = 5; + final int intervAngle = 10; + final double theta = Math.PI * 2 / intervAngle; + for (int a = 0; a < 10; a++) { + final AffineTransform at = AffineTransform.getRotateInstance(theta * a, p1.x, p1.y); + for (int i = 0; i < interv * 2; i++) { + final Point2D.Double p = new Point2D.Double(p1.x + dx * i / interv, p1.y + dy * i / interv); + result.add((Point2D.Double) at.transform(p, null)); + } + } + + } + + public List get() { + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/Measurer.java b/src/net/sourceforge/plantuml/graph2/Measurer.java new file mode 100644 index 000000000..5f3c6e96d --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/Measurer.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +public interface Measurer { + int getMeasure(V data); +} diff --git a/src/net/sourceforge/plantuml/graph2/MyCurve.java b/src/net/sourceforge/plantuml/graph2/MyCurve.java new file mode 100644 index 000000000..0017aba94 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/MyCurve.java @@ -0,0 +1,171 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.List; + +public class MyCurve { + + private final CubicCurve2D.Double curve; + private final List lines = new ArrayList(); + private final List linesForInters = new ArrayList(); + private Color color = Color.GREEN; + private double lenght = 0; + + public MyCurve(CubicCurve2D.Double curve) { + this.curve = curve; + addCurve(curve); + if (lenght <= 0) { + throw new IllegalStateException(); + } + for (Line2D.Double line : lines) { + linesForInters.add(change(line, curve.getP1(), curve.getP2())); + } + } + + private Line2D.Double change(Line2D.Double line, Point2D p1, Point2D p2) { + if (line.getP1().equals(p1) == false && line.getP2().equals(p2) == false) { + return line; + } + final double dx = line.x2 - line.x1; + final double dy = line.y2 - line.y1; + if (line.getP1().equals(p1)) { + p1 = new Point2D.Double(line.x1 + dx / 10, line.y1 + dy / 10); + } else { + p1 = line.getP1(); + } + if (line.getP2().equals(p2)) { + p2 = new Point2D.Double(line.x2 - dx / 10, line.y2 - dy / 10); + } else { + p2 = line.getP2(); + } + return new Line2D.Double(p1, p2); + } + + public final double getLenght() { + return lenght; + } + + private void addCurve(CubicCurve2D.Double peace) { + final Rectangle2D bounds = peace.getBounds2D(); + final double flat = peace.getFlatness(); + if (flat < 10) { + lines.add(new Line2D.Double(peace.getP1(), peace.getP2())); + lenght += Math.sqrt(bounds.getWidth() * bounds.getWidth() + bounds.getHeight() * bounds.getHeight()); + return; + } + final CubicCurve2D.Double left = new CubicCurve2D.Double(); + final CubicCurve2D.Double right = new CubicCurve2D.Double(); + peace.subdivide(left, right); + addCurve(left); + addCurve(right); + } + + public void drawDebug(Graphics2D g2d) { + for (Line2D r : linesForInters) { + g2d.setColor(color); + g2d.draw(r); + } + g2d.setColor(Color.BLACK); + // g2d.draw(curve); + } + + public void draw(Graphics2D g2d) { + g2d.setStroke(new BasicStroke((float) 1.5)); + g2d.draw(curve); + g2d.setStroke(new BasicStroke()); + } + + public final void setColor(Color color) { + this.color = color; + } + + public boolean intersects(List others) { + for (MyCurve other : others) { + if (this.intersects(other)) { + return true; + } + } + return false; + } + + private boolean intersects(MyCurve other) { + for (Line2D.Double l1 : this.linesForInters) { + for (Line2D.Double l2 : other.linesForInters) { + if (l1.intersectsLine(l2)) { + return true; + } + } + } + return false; + } + + public boolean intersects(RectanglesCollection forbidden) { + for (Rectangle2D.Double r : forbidden) { + for (Line2D.Double line : lines) { + if (r.intersectsLine(line)) { + return true; + } + } + } + return false; + } + // public static long TPS6; + // + // public RectanglesCollection unrecoveredBy(RectanglesCollection allFrames) + // { + // final long start = System.currentTimeMillis(); + // try { + // final RectanglesCollection result = new RectanglesCollection(); + // for (Rectangle2D.Double r : areas) { + // if (allFrames.intersect(new RectanglesCollection(r)) == false) { + // result.add(r); + // } + // } + // return result; + // } finally { + // TPS6 += System.currentTimeMillis() - start; + // } + // } + // + +} diff --git a/src/net/sourceforge/plantuml/graph2/Neighborhood2.java b/src/net/sourceforge/plantuml/graph2/Neighborhood2.java new file mode 100644 index 000000000..2b85f97ed --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/Neighborhood2.java @@ -0,0 +1,188 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.geom.Orientation; + +public class Neighborhood2 { + + final private double angle1; + final private double angle2; + final private Point2D.Double center; + + public Neighborhood2(Point2D.Double center) { + this(center, 0, 0); + } + + public boolean is360() { + return angle1 == angle2; + } + + public Neighborhood2(Point2D.Double center, double angle1, double angle2) { + this.center = center; + this.angle1 = angle1; + this.angle2 = angle2; + } + + @Override + public boolean equals(Object obj) { + final Neighborhood2 other = (Neighborhood2) obj; + return angle1 == other.angle1 && angle2 == other.angle2 && center.equals(other.center); + } + + @Override + public int hashCode() { + return center.hashCode() * 17 + new Point2D.Double(angle1, angle2).hashCode(); + } + + @Override + public String toString() { + final int a1 = (int) (angle1 * 180 / Math.PI); + final int a2 = (int) (angle2 * 180 / Math.PI); + return center + " " + a1 + " " + a2; + } + + public final Point2D.Double getCenter() { + return center; + } + + // private double getMiddle() { + // if (is360()) { + // return angle1 + 2 * Math.PI / 3; + // } + // double result = (angle1 + angle2) / 2; + // if (angle2 < angle1) { + // result += Math.PI; + // } + // return result; + // } + // + public Point2D.Double getPointInNeighborhood(double dist, Point2D p1, Point2D p2) { + if (p1 == null || p2 == null) { + throw new IllegalArgumentException(); + } + if (dist <= 0) { + throw new IllegalArgumentException(); + } + final double v1 = Singularity2.convertAngle(Singularity2.getAngle(new Line2D.Double(center, p1)) - angle1); + final double v2 = Singularity2.convertAngle(Singularity2.getAngle(new Line2D.Double(center, p2)) - angle1); + if (v1 < 0) { + throw new IllegalStateException(); + } + if (v2 < 0) { + throw new IllegalStateException(); + } + final double middle = (v1 + v2) / 2 + angle1; + return new Point2D.Double(center.x + dist * Math.cos(middle), center.y + dist * Math.sin(middle)); + } + + public boolean isInAngleStrict(double angle) { + if (angle < 0) { + throw new IllegalArgumentException(); + } + if (angle2 > angle1) { + return angle > angle1 && angle < angle2; + } + return angle > angle1 || angle < angle2; + } + + public boolean isInAngleLarge(double angle) { + if (angle < 0) { + throw new IllegalArgumentException(); + } + if (angle2 > angle1) { + return angle >= angle1 && angle <= angle2; + } + return angle >= angle1 || angle <= angle2; + } + + public boolean isAngleLimit(double angle) { + return angle == angle1 || angle == angle2; + } + + public Orientation getOrientationFrom(double angle) { + if (angle1 == angle2) { + throw new IllegalStateException(); + } + if (angle != angle1 && angle != angle2) { + throw new IllegalArgumentException("this=" + this + " angle=" + (int) (angle * 180 / Math.PI)); + } + assert angle == angle1 || angle == angle2; + + if (angle == angle1) { + return Orientation.MATH; + } + return Orientation.CLOCK; + } + + public boolean isConnectable(Neighborhood2 other) { + assert isConnectableInternal(other) == other.isConnectableInternal(this); + return isConnectableInternal(other); + + } + + private boolean isConnectableInternal(Neighborhood2 other) { + if (getCenter().equals(other.getCenter())) { + throw new IllegalArgumentException("Same center"); + } + final Line2D.Double seg1 = new Line2D.Double(getCenter(), other.getCenter()); + + final double angle1 = Singularity2.convertAngle(Singularity2.getAngle(seg1)); + final double angle2 = Singularity2.convertAngle(Singularity2.getOppositeAngle(seg1)); + assert angle2 == Singularity2.convertAngle(Singularity2.getAngle(new Line2D.Double(other.getCenter(), + getCenter()))); + if (isInAngleStrict(angle1) && other.isInAngleStrict(angle2)) { + return true; + } + if (isInAngleStrict(angle1) && other.isInAngleLarge(angle2)) { + return true; + } + if (isInAngleLarge(angle1) && other.isInAngleStrict(angle2)) { + return true; + } + if (isAngleLimit(angle1) && other.isAngleLimit(angle2)) { + if (is360() || other.is360()) { + return true; + } + final Orientation o1 = getOrientationFrom(angle1); + final Orientation o2 = other.getOrientationFrom(angle2); + return o1 != o2; + } + return false; + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/Plan.java b/src/net/sourceforge/plantuml/graph2/Plan.java new file mode 100644 index 000000000..b25e0e5e5 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/Plan.java @@ -0,0 +1,252 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.graph2.Dijkstra.Vertex; + +public class Plan { + + private final Map points = new LinkedHashMap(); + private final Collection lines = new ArrayList(); + + public void addPoint2D(Point2D.Double point) { + if (points.containsKey(point)) { + throw new IllegalArgumentException(); + } + points.put(point, new Singularity2(point)); + } + + public void debugPrint() { + System.err.println("PLAN PRINT"); + for (Singularity2 s : points.values()) { + System.err.println(s); + } + for (Line2D.Double l : lines) { + System.err.println(GeomUtils.toString(l)); + } + } + + public void createLink(Point2D p1, Point2D p2) { + final Singularity2 s1 = points.get(p1); + final Singularity2 s2 = points.get(p2); + if (s1 == null || s2 == null) { + throw new IllegalArgumentException(); + } + final Line2D.Double line = new Line2D.Double(p1, p2); + + s1.addLineSegment(line); + s2.addLineSegment(line); + lines.add(line); + } + + Singularity2 getSingularity(Point2D pt) { + final Singularity2 result = points.get(pt); + if (result == null) { + throw new IllegalArgumentException(); + } + return result; + } + + List getShortestPathToInternal(Point2D start, Point2D end) { + final Dijkstra dijkstra = new Dijkstra(); + if (points.containsKey(start) == false || points.containsKey(end) == false) { + throw new IllegalArgumentException(); + } + final Vertex vStart = dijkstra.addVertex(start); + final Vertex vEnd = dijkstra.addVertex(end); + final Map vertexes = new LinkedHashMap(); + for (Singularity2 s : points.values()) { + for (Neighborhood2 n : s.getNeighborhoods()) { + final Vertex v = dijkstra.addVertex(n); + vertexes.put(n, v); + if (n.getCenter().equals(start)) { + vStart.addAdjacencies(v, 0.01); + } + if (n.getCenter().equals(end)) { + v.addAdjacencies(vEnd, 0.01); + } + } + } + + for (Vertex v1 : vertexes.values()) { + for (Vertex v2 : vertexes.values()) { + final Neighborhood2 n1 = (Neighborhood2) v1.getData(); + final Neighborhood2 n2 = (Neighborhood2) v2.getData(); + if (n1.getCenter().equals(n2.getCenter())) { + continue; + } + final Line2D.Double line = new Line2D.Double(n1.getCenter(), n2.getCenter()); + if (isStrictCrossing(line)) { + continue; + } + if (n1.isConnectable(n2) == false) { + continue; + } + final double dist = n1.getCenter().distance(n2.getCenter()); + v1.addAdjacencies(v2, dist); + v2.addAdjacencies(v1, dist); + // System.err.println("=(" + n1 + ") (" + n2 + ") " + dist); + } + } + + final List list = dijkstra.getShortestPathTo(vStart, vEnd); + if (list.size() < 2) { + throw new IllegalStateException("list=" + list); + } + final List result = new ArrayList(); + for (Vertex v : list.subList(1, list.size() - 1)) { + result.add((Neighborhood2) v.getData()); + } + return result; + } + + public List getIntermediatePoints(Point2D start, Point2D end) { + // System.err.println("start=" + start + " end=" + end); + final List result = new ArrayList(); + final List list = getShortestPathToInternal(start, end); + // System.err.println("Neighborhood2 = " + list); + for (int i = 1; i < list.size() - 1; i++) { + final Neighborhood2 n = list.get(i); + final Point2D.Double before = list.get(i - 1).getCenter(); + final Point2D.Double after = list.get(i + 1).getCenter(); + // System.err.println("before="+before); + // System.err.println("after="+after); + // System.err.println("n.getCenter()="+n.getCenter()); + // System.err.println("getMindist(n.getCenter())="+getMindist(n.getCenter())); + final Point2D.Double pointInNeighborhood = n.getPointInNeighborhood(getMindist(n.getCenter()) / 2, before, + after); + // System.err.println("pointInNeighborhood="+pointInNeighborhood); + result.add(pointInNeighborhood); + } + return result; + + } + + private boolean isStrictCrossing(Line2D.Double line) { + for (Line2D.Double l : lines) { + if (intersectsLineStrict(l, line)) { + return true; + } + } + return false; + } + + public static boolean intersectsLineStrict(Line2D.Double l1, Line2D.Double l2) { + assert intersectsLineStrictInternal(l1, l2) == intersectsLineStrictInternal(l2, l1); + assert intersectsLineStrictInternal(l1, l2) == intersectsLineStrictInternal(inverse(l1), l2); + assert intersectsLineStrictInternal(l1, l2) == intersectsLineStrictInternal(l1, inverse(l2)); + assert intersectsLineStrictInternal(l1, l2) == intersectsLineStrictInternal(inverse(l1), inverse(l2)); + return intersectsLineStrictInternal(l1, l2); + } + + private static Line2D.Double inverse(Line2D.Double line) { + return new Line2D.Double(line.getP2(), line.getP1()); + } + + private static boolean intersectsLineStrictInternal(Line2D.Double l1, Line2D.Double l2) { + if (l1.intersectsLine(l2) == false) { + return false; + } + assert l1.intersectsLine(l2); + + Point2D.Double l1a = (Point2D.Double) l1.getP1(); + Point2D.Double l1b = (Point2D.Double) l1.getP2(); + Point2D.Double l2a = (Point2D.Double) l2.getP1(); + Point2D.Double l2b = (Point2D.Double) l2.getP2(); + + if (l1a.equals(l2a) == false && l1a.equals(l2b) == false && l1b.equals(l2a) == false + && l1b.equals(l2b) == false) { + return true; + } + + if (l1a.equals(l2b)) { + final Point2D.Double tmp = l2a; + l2a = l2b; + l2b = tmp; + } else if (l2a.equals(l1b)) { + final Point2D.Double tmp = l1a; + l1a = l1b; + l1b = tmp; + } else if (l1b.equals(l2b)) { + Point2D.Double tmp = l2a; + l2a = l2b; + l2b = tmp; + tmp = l1a; + l1a = l1b; + l1b = tmp; + } + + assert l1a.equals(l2a); + + return false; + + } + + final double getMindist(Point2D.Double pt) { + double result = Double.MAX_VALUE; + for (Point2D p : points.keySet()) { + if (pt.equals(p)) { + continue; + } + final double v = p.distance(pt); + if (v < 1E-4) { + throw new IllegalStateException(); + } + result = Math.min(result, v); + } + for (Line2D line : lines) { + if (line.getP1().equals(pt) || line.getP2().equals(pt)) { + continue; + } + final double v = line.ptSegDist(pt); + if (result < 1E-4) { + throw new IllegalStateException("pt=" + pt + " line=" + GeomUtils.toString(line)); + } + result = Math.min(result, v); + } + if (result == 0) { + throw new IllegalStateException(); + } + // System.err.println("getMindist=" + result); + return result; + } +} diff --git a/src/net/sourceforge/plantuml/graph2/Polyline2.java b/src/net/sourceforge/plantuml/graph2/Polyline2.java new file mode 100644 index 000000000..0a73cad0c --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/Polyline2.java @@ -0,0 +1,109 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.QuadCurve2D; +import java.util.ArrayList; +import java.util.List; + +public class Polyline2 { + + private final List lines = new ArrayList(); + private Point2D lastCurrent; + private final Point2D end; + + public Polyline2(Point2D start, Point2D end) { + lastCurrent = start; + this.end = end; + } + + public void addLine(Line2D.Double newLine) { + // System.err.println("# Polyline2::addLine " + + // GeomUtils.toString(newLine)); + if (lastCurrent.equals(newLine.getP1()) == false) { + lines.add(new Line2D.Double(lastCurrent, newLine.getP1())); + } + lines.add(newLine); + lastCurrent = newLine.getP2(); + } + + private boolean debug = false; + + public void draw(Graphics2D g2d) { + close(); + if (debug) { + g2d.setColor(Color.GREEN); + drawDebug(g2d); + } + g2d.setColor(Color.BLUE); + final List centers = new ArrayList(); + for (Line2D.Double l : lines) { + centers.add(GeomUtils.getCenter(l)); + } + g2d.draw(new Line2D.Double(lines.get(0).getP1(), centers.get(0))); + g2d.draw(new Line2D.Double(centers.get(centers.size() - 1), end)); + for (int i = 0; i < lines.size() - 1; i++) { + final Point2D c1 = centers.get(i); + final Point2D c2 = centers.get(i + 1); + final Point2D ctrl = lines.get(i).getP2(); + assert ctrl.equals(lines.get(i + 1).getP1()); + final QuadCurve2D.Double quad = new QuadCurve2D.Double(c1.getX(), c1.getY(), ctrl.getX(), ctrl.getY(), c2 + .getX(), c2.getY()); + g2d.draw(quad); + } + if (debug) { + for (Point2D.Double c : centers) { + GeomUtils.fillPoint2D(g2d, c); + } + } + } + + private void drawDebug(Graphics2D g2d) { + for (Line2D.Double l : lines) { + g2d.draw(l); + GeomUtils.fillPoint2D(g2d, l.getP1()); + GeomUtils.fillPoint2D(g2d, l.getP2()); + } + } + + private void close() { + if (lastCurrent.equals(end) == false) { + lines.add(new Line2D.Double(lastCurrent, end)); + } + } +} diff --git a/src/net/sourceforge/plantuml/graph2/RectanglesCollection.java b/src/net/sourceforge/plantuml/graph2/RectanglesCollection.java new file mode 100644 index 000000000..33b635b89 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/RectanglesCollection.java @@ -0,0 +1,198 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class RectanglesCollection implements Iterable { + + private final List areas = new ArrayList(); + private final SortedListImpl sortedX1; + private final SortedListImpl sortedX2; + private final SortedListImpl sortedY1; + private final SortedListImpl sortedY2; + + private Rectangle2D.Double max = null; + + public RectanglesCollection() { + sortedX1 = new SortedListImpl(new Measurer() { + public int getMeasure(Rectangle2D.Double data) { + return (int) data.x; + } + }); + sortedX2 = new SortedListImpl(new Measurer() { + public int getMeasure(Rectangle2D.Double data) { + return (int) (data.x + data.width); + } + }); + sortedY1 = new SortedListImpl(new Measurer() { + public int getMeasure(Rectangle2D.Double data) { + return (int) data.y; + } + }); + sortedY2 = new SortedListImpl(new Measurer() { + public int getMeasure(Rectangle2D.Double data) { + return (int) (data.y + data.height); + } + }); + } + + public RectanglesCollection(Rectangle2D.Double rect) { + this(); + add(rect); + } + + public double getSurf() { + if (max == null) { + return 0; + } + return max.getWidth() * max.getHeight(); + } + + public void add(Rectangle2D.Double rect) { + areas.add(rect); + // sortedX1.add(rect); + // sortedX2.add(rect); + // sortedY1.add(rect); + // sortedY2.add(rect); + if (max == null) { + max = rect; + } else { + max = (Rectangle2D.Double) max.createUnion(rect); + } + } + + public Iterator iterator() { + return areas.iterator(); + } + + public boolean intersect(RectanglesCollection other) { + if (this.size() > other.size()) { + return intersectSeveral(this, other); + } + return intersectSeveral(other, this); + } + + static public long TPS1; + static public long TPS2; + + private static boolean intersectSeveral(RectanglesCollection large, RectanglesCollection compact) { + assert large.size() >= compact.size(); + final long start = System.currentTimeMillis(); + try { + for (Rectangle2D.Double r : compact) { + if (large.intersectSimple(r)) { + return true; + } + } + return false; + } finally { + TPS2 += System.currentTimeMillis() - start; + } + } + + private boolean intersectSimple(Rectangle2D.Double rect) { + final long start = System.currentTimeMillis(); + try { + if (max == null || max.intersects(rect) == false) { + return false; + } + for (Rectangle2D.Double r : areas) { + if (rect.intersects(r)) { + return true; + } + } + return false; + } finally { + TPS1 += System.currentTimeMillis() - start; + } + } + + private boolean intersectSimpleOld(Rectangle2D.Double rect) { + final long start = System.currentTimeMillis(); + try { + if (max == null || max.intersects(rect) == false) { + return false; + } + final List lX1 = sortedX1.lesserOrEquals((int) (rect.x + rect.width)); + List lmin = lX1; + if (lX1.size() == 0) { + return false; + } + final List lX2 = sortedX2.biggerOrEquals((int) rect.x); + if (lX2.size() == 0) { + return false; + } + if (lX2.size() < lmin.size()) { + lmin = lX2; + } + final List lY1 = sortedY1.lesserOrEquals((int) (rect.y + rect.height)); + if (lY1.size() == 0) { + return false; + } + if (lY1.size() < lmin.size()) { + lmin = lY1; + } + final List lY2 = sortedY2.biggerOrEquals((int) rect.y); + if (lY2.size() == 0) { + return false; + } + if (lY2.size() < lmin.size()) { + lmin = lY2; + } + for (Rectangle2D.Double r : lmin) { + if (rect.intersects(r)) { + return true; + } + } + return false; + } finally { + TPS1 += System.currentTimeMillis() - start; + } + } + + public int size() { + return areas.size(); + } + + public void addAll(RectanglesCollection other) { + for (Rectangle2D.Double r : other.areas) { + this.add(r); + } + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/Singularity2.java b/src/net/sourceforge/plantuml/graph2/Singularity2.java new file mode 100644 index 000000000..f24ef7c11 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/Singularity2.java @@ -0,0 +1,162 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.TreeSet; + +public class Singularity2 { + + private final TreeSet angles = new TreeSet(); + + final private Point2D.Double center; + + public Singularity2(Point2D.Double center) { + this.center = center; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(center.toString()); + for (Double a : angles) { + final int degree = (int) (a * 180 / Math.PI); + sb.append(' '); + sb.append(degree); + } + return sb.toString(); + } + + public void addLineSegment(Line2D.Double seg) { + if (seg.getP1().equals(center)) { + angles.add(convertAngle(getAngle(seg))); + } else if (seg.getP2().equals(center)) { + angles.add(convertAngle(getOppositeAngle(seg))); + } else { + throw new IllegalArgumentException(); + } + assert betweenZeroAndTwoPi(); + + } + + static final double getAngle(Line2D.Double line) { + if (line.getP1().equals(line.getP2())) { + throw new IllegalArgumentException(); + } + return Math.atan2(line.getP2().getY() - line.getP1().getY(), line.getP2().getX() - line.getP1().getX()); + } + + static final double getOppositeAngle(Line2D.Double line) { + return Math.atan2(line.getP1().getY() - line.getP2().getY(), line.getP1().getX() - line.getP2().getX()); + } + + static double convertAngle(double a) { + while (a < 0) { + a += 2 * Math.PI; + } + return a; + } + + private boolean betweenZeroAndTwoPi() { + for (Double d : angles) { + assert d >= 0; + assert d < 2 * Math.PI; + } + return true; + } + + List getAngles() { + return new ArrayList(angles); + } + + public boolean crossing(Point2D.Double direction1, Point2D.Double direction2) { + final boolean result = crossingInternal(direction1, direction2); + assert result == crossingInternal(direction2, direction1); + return result; + } + + private boolean crossingInternal(Point2D.Double direction1, Point2D.Double direction2) { + if (angles.size() < 2) { + return false; + } + final double angle1 = convertAngle(getAngle(new Line2D.Double(center, direction1))); + final double angle2 = convertAngle(getAngle(new Line2D.Double(center, direction2))); + + Double last = null; + for (Double current : angles) { + if (last != null) { + assert last < current; + if (isBetween(angle1, last, current) && isBetween(angle2, last, current)) { + return false; + } + } + last = current; + } + final double first = angles.first(); + if ((angle1 <= first || angle1 >= last) && (angle2 <= first || angle2 >= last)) { + return false; + } + return true; + } + + private boolean isBetween(double test, double v1, double v2) { + assert v1 < v2; + return test >= v1 && test <= v2; + } + + protected final Point2D.Double getCenter() { + return center; + } + + public void merge(Singularity2 other) { + this.angles.addAll(other.angles); + } + + public List getNeighborhoods() { + if (angles.size() == 0) { + return Collections.singletonList(new Neighborhood2(center)); + } + final List result = new ArrayList(); + double last = angles.last(); + for (Double currentAngle : angles) { + result.add(new Neighborhood2(center, last, currentAngle)); + last = currentAngle; + } + return Collections.unmodifiableList(result); + } + +} diff --git a/src/net/sourceforge/plantuml/graph2/SortedList.java b/src/net/sourceforge/plantuml/graph2/SortedList.java new file mode 100644 index 000000000..377e48c11 --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/SortedList.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.util.List; + +public interface SortedList extends Iterable { + public void add(V data); + + public List lesserOrEquals(int v); + + public List biggerOrEquals(int v); +} diff --git a/src/net/sourceforge/plantuml/graph2/SortedListImpl.java b/src/net/sourceforge/plantuml/graph2/SortedListImpl.java new file mode 100644 index 000000000..dbda3b5aa --- /dev/null +++ b/src/net/sourceforge/plantuml/graph2/SortedListImpl.java @@ -0,0 +1,127 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3833 $ + * + */ +package net.sourceforge.plantuml.graph2; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +public class SortedListImpl implements SortedList { + + static class NullableAndEvenMeasurer implements Measurer { + private final Measurer wrapped; + private final int valueForNull; + + NullableAndEvenMeasurer(Measurer wrapped, int valueForNull, boolean plus) { + this.wrapped = wrapped; + if (plus) { + this.valueForNull = valueForNull * 2 + 1; + } else { + this.valueForNull = valueForNull * 2 - 1; + } + } + + public int getMeasure(V data) { + if (data == null) { + return valueForNull; + } + return wrapped.getMeasure(data) * 2; + } + } + + private final Measurer measurer; + private final List all = new ArrayList(); + private final Comparator comparator; + + public SortedListImpl(Measurer m) { + this.measurer = m; + this.comparator = new Comparator() { + public int compare(V o1, V o2) { + final int v1 = measurer.getMeasure(o1); + final int v2 = measurer.getMeasure(o2); + return v1 - v2; + } + }; + } + + public void add(V data) { + final int pos = Collections.binarySearch(all, data, comparator); + if (pos >= 0) { + all.add(pos, data); + } else { + all.add(-pos - 1, data); + } + assert isSorted(); + } + + private int getPos(int v, boolean plus) { + final Measurer m = new NullableAndEvenMeasurer(measurer, v, plus); + final Comparator myComp = new Comparator() { + public int compare(V o1, V o2) { + final int v1 = m.getMeasure(o1); + final int v2 = m.getMeasure(o2); + return v1 - v2; + } + }; + final int pos = Collections.binarySearch(all, null, myComp); + assert pos < 0; + return -pos - 1; + } + + public List lesserOrEquals(int v) { + return all.subList(0, getPos(v, true)); + } + + public List biggerOrEquals(int v) { + return all.subList(getPos(v, false), all.size()); + } + + private boolean isSorted() { + for (int i = 0; i < all.size() - 1; i++) { + final int v1 = measurer.getMeasure(all.get(i)); + final int v2 = measurer.getMeasure(all.get(i + 1)); + if (v1 > v2) { + return false; + } + } + return true; + } + + public Iterator iterator() { + return all.iterator(); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/AddStyle.java b/src/net/sourceforge/plantuml/graphic/AddStyle.java new file mode 100644 index 000000000..89281c569 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/AddStyle.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5506 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; + +class AddStyle implements FontChange { + + private final FontStyle style; + private final Color extendedColor; + + AddStyle(FontStyle style, Color extendedColor) { + this.style = style; + this.extendedColor = extendedColor; + } + + public AddStyle(String s) { + this(FontStyle.getStyle(s), FontStyle.getStyle(s).getExtendedColor(s)); + } + + public FontConfiguration apply(FontConfiguration initial) { + initial = initial.add(style); + if (extendedColor != null) { + initial = initial.changeExtendedColor(extendedColor); + } + return initial; + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/CircledCharacter.java b/src/net/sourceforge/plantuml/graphic/CircledCharacter.java new file mode 100644 index 000000000..94475fa6c --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/CircledCharacter.java @@ -0,0 +1,136 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4917 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.awt.geom.Dimension2D; +import java.awt.geom.PathIterator; + +import net.sourceforge.plantuml.skin.UDrawable; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPath; +import net.sourceforge.plantuml.ugraphic.USegmentType; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; + +public class CircledCharacter implements UDrawable { + + private final String c; + private final Font font; + private final Color innerCircle; + private final Color circle; + private final Color fontColor; + private final double radius; + + public CircledCharacter(char c, double radius, Font font, Color innerCircle, Color circle, Color fontColor) { + this.c = "" + c; + this.radius = radius; + this.font = font; + this.innerCircle = innerCircle; + this.circle = circle; + this.fontColor = fontColor; + } + + public void draw(Graphics2D g2d, int x, int y) { + drawU(new UGraphicG2d(g2d, null), x, y); + } + + public void drawU(UGraphic ug, double x, double y) { + + if (circle != null) { + ug.getParam().setColor(circle); + } + +// final Color circleToUse = circle == null ? ug.getParam().getColor() : circle; +// ug.getParam().setColor(circleToUse); + + ug.getParam().setBackcolor(innerCircle); + + ug.draw(x, y, new UEllipse(radius * 2, radius * 2)); + + ug.getParam().setColor(fontColor); + + // if (ug instanceof UGraphicSvg) { + // final UPath p = getUPath(new FontRenderContext(null, true, true)); + // ug.draw(x + radius, y + radius, p); + // } else { + ug.centerChar(x + radius, y + radius, c.charAt(0), font); + // } + + } + + private Dimension2D getStringDimension(StringBounder stringBounder) { + return stringBounder.calculateDimension(font, c); + } + + final public double getPreferredWidth(StringBounder stringBounder) { + return 2 * radius; + } + + final public double getPreferredHeight(StringBounder stringBounder) { + return 2 * radius; + } + + public void drawU(UGraphic ug) { + drawU(ug, 0, 0); + } + + private PathIterator getPathIteratorCharacter(FontRenderContext frc) { + final TextLayout textLayout = new TextLayout(c, font, frc); + final Shape s = textLayout.getOutline(null); + return s.getPathIterator(null); + } + + public UPath getUPath(FontRenderContext frc) { + final UPath result = new UPath(); + + final PathIterator path = getPathIteratorCharacter(frc); + + final double coord[] = new double[6]; + while (path.isDone() == false) { + // final int w = path.getWindingRule(); + final int code = path.currentSegment(coord); + result.add(coord, USegmentType.getByCode(code)); + path.next(); + } + + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/ColorAndSizeChange.java b/src/net/sourceforge/plantuml/graphic/ColorAndSizeChange.java new file mode 100644 index 000000000..d56c497e7 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/ColorAndSizeChange.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class ColorAndSizeChange implements FontChange { + + static final Pattern colorPattern = Pattern.compile("(?i)color\\s*=\\s*\"?(#[0-9a-fA-F]{6}|\\w+)\"?"); + + static final Pattern sizePattern = Pattern.compile("(?i)size\\s*=\\s*\"?(\\d+)\"?"); + + private final HtmlColor color; + private final Integer size; + + ColorAndSizeChange(String s) { + final Matcher matcherColor = colorPattern.matcher(s); + if (matcherColor.find()) { + color = new HtmlColor(matcherColor.group(1)); + } else { + color = null; + } + final Matcher matcherSize = sizePattern.matcher(s); + if (matcherSize.find()) { + size = new Integer(matcherSize.group(1)); + } else { + size = null; + } + } + + HtmlColor getColor() { + return color; + } + + Integer getSize() { + return size; + } + + public FontConfiguration apply(FontConfiguration initial) { + FontConfiguration result = initial; + if (color != null) { + result = result.changeColor(color); + } + if (size != null) { + result = result.changeSize(size); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/ColorChange.java b/src/net/sourceforge/plantuml/graphic/ColorChange.java new file mode 100644 index 000000000..5e63a05d6 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/ColorChange.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class ColorChange implements FontChange { + + static private final Pattern colorPattern = Pattern.compile("(?i)" + Splitter.fontColorPattern2); + + private final HtmlColor color; + + ColorChange(String s) { + final Matcher matcherColor = colorPattern.matcher(s); + if (matcherColor.find() == false) { + throw new IllegalArgumentException(); + } + this.color = new HtmlColor(matcherColor.group(1)); + } + + HtmlColor getColor() { + return color; + } + + public FontConfiguration apply(FontConfiguration initial) { + return initial.changeColor(color); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/FontChange.java b/src/net/sourceforge/plantuml/graphic/FontChange.java new file mode 100644 index 000000000..b75d7b055 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/FontChange.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +public interface FontChange extends HtmlCommand { + + FontConfiguration apply(FontConfiguration initial); +} diff --git a/src/net/sourceforge/plantuml/graphic/FontConfiguration.java b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java new file mode 100644 index 000000000..a9f97962f --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/FontConfiguration.java @@ -0,0 +1,116 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5506 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.util.EnumSet; + +public class FontConfiguration { + + private final EnumSet styles; + private final Font currentFont; + private final Font motherFont; + private final Color motherColor; + private final Color currentColor; + private final Color extendedColor; + + public FontConfiguration(Font font, Color color) { + this(EnumSet.noneOf(FontStyle.class), font, color, font, color, null); + } + + @Override + public String toString() { + return styles.toString()+" "+currentColor; + } + + private FontConfiguration(EnumSet styles, Font motherFont, Color motherColor, Font currentFont, + Color currentColor, Color extendedColor) { + this.styles = styles; + this.currentFont = currentFont; + this.motherFont = motherFont; + this.currentColor = currentColor; + this.motherColor = motherColor; + this.extendedColor = extendedColor; + } + + FontConfiguration changeColor(HtmlColor htmlColor) { + return new FontConfiguration(styles, motherFont, motherColor, currentFont, htmlColor.getColor(), extendedColor); + } + + FontConfiguration changeExtendedColor(Color newExtendedColor) { + return new FontConfiguration(styles, motherFont, motherColor, currentFont, currentColor, newExtendedColor); + } + + FontConfiguration changeSize(float size) { + return new FontConfiguration(styles, motherFont, motherColor, currentFont.deriveFont(size), currentColor, extendedColor); + } + + public FontConfiguration resetFont() { + return new FontConfiguration(styles, motherFont, motherColor, motherFont, motherColor, null); + } + + FontConfiguration add(FontStyle style) { + final EnumSet r = styles.clone(); + r.add(style); + return new FontConfiguration(r, motherFont, motherColor, currentFont, currentColor, extendedColor); + } + + FontConfiguration remove(FontStyle style) { + final EnumSet r = styles.clone(); + r.remove(style); + return new FontConfiguration(r, motherFont, motherColor, currentFont, currentColor, extendedColor); + } + + public Font getFont() { + Font result = currentFont; + for (FontStyle style : styles) { + result = style.mutateFont(result); + } + return result; + } + + public Color getColor() { + return currentColor; + } + + public Color getExtendedColor() { + return extendedColor; + } + + public boolean containsStyle(FontStyle style) { + return styles.contains(style); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/FontStyle.java b/src/net/sourceforge/plantuml/graphic/FontStyle.java new file mode 100644 index 000000000..106429d9e --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/FontStyle.java @@ -0,0 +1,117 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5507 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.util.EnumSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public enum FontStyle { + PLAIN, ITALIC, BOLD, UNDERLINE, STRIKE, WAVE; + + public Font mutateFont(Font font) { + if (this == ITALIC) { + return font.deriveFont(font.getStyle() | Font.ITALIC); + } + if (this == BOLD) { + return font.deriveFont(font.getStyle() | Font.BOLD); + } + return font; + } + + public String getActivationPattern() { + if (this == ITALIC) { + return "\\<[iI]\\>"; + } + if (this == BOLD) { + return "\\<[bB]\\>"; + } + if (this == UNDERLINE) { + return "\\<[uU](?::(#[0-9a-fA-F]{6}|\\w+))?\\>"; + } + if (this == WAVE) { + return "\\<[wW](?::(#[0-9a-fA-F]{6}|\\w+))?\\>"; + } + if (this == STRIKE) { + return "\\<(?:s|S|strike|STRIKE|del|DEL)(?::(#[0-9a-fA-F]{6}|\\w+))?\\>"; + } + return null; + } + + Color getExtendedColor(String s) { + final Matcher m = Pattern.compile(getActivationPattern()).matcher(s); + if (m.find() == false || m.groupCount() != 1) { + return null; + } + final String color = m.group(1); + if (color!= null && HtmlColor.isValid(color)) { + return new HtmlColor(color).getColor(); + } + return null; + } + + public String getDeactivationPattern() { + if (this == ITALIC) { + return "\\"; + } + if (this == BOLD) { + return "\\"; + } + if (this == UNDERLINE) { + return "\\"; + } + if (this == WAVE) { + return "\\"; + } + if (this == STRIKE) { + return "\\"; + } + return null; + } + + public static FontStyle getStyle(String line) { + for (FontStyle style : EnumSet.allOf(FontStyle.class)) { + if (style == FontStyle.PLAIN) { + continue; + } + if (line.matches(style.getActivationPattern()) || line.matches(style.getDeactivationPattern())) { + return style; + } + } + throw new IllegalArgumentException(line); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/GraphicPosition.java b/src/net/sourceforge/plantuml/graphic/GraphicPosition.java new file mode 100644 index 000000000..47ab343dc --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/GraphicPosition.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5138 $ + * + */ +package net.sourceforge.plantuml.graphic; + + +public enum GraphicPosition { + BOTTOM, BACKGROUND_CORNER + +} diff --git a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java new file mode 100644 index 000000000..0864acb9a --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java @@ -0,0 +1,154 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5326 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.Dimension2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; +import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class GraphicStrings { + + private final Color background; + + private final Font font; + + private final Color green; + + private final List strings; + + private final BufferedImage image; + + private final GraphicPosition position; + + private final boolean disableTextAliasing; + + public GraphicStrings(List strings) { + this(strings, new Font("SansSerif", Font.BOLD, 14), new Color(Integer.parseInt("33FF02", 16)), Color.BLACK, + null, null, false); + } + + public GraphicStrings(List strings, BufferedImage image) { + this(strings, new Font("SansSerif", Font.BOLD, 14), new Color(Integer.parseInt("33FF02", 16)), Color.BLACK, + image, null, false); + } + + public GraphicStrings(List strings, Font font, Color green, Color background, boolean disableTextAliasing) { + this(strings, font, green, background, null, null, disableTextAliasing); + } + + public GraphicStrings(List strings, Font font, Color green, Color background, BufferedImage image, + GraphicPosition position, boolean disableTextAliasing) { + this.strings = strings; + this.font = font; + this.green = green; + this.background = background; + this.image = image; + this.position = position; + this.disableTextAliasing = disableTextAliasing; + } + + public void writeImage(OutputStream os, FileFormat fileFormat) throws IOException { + writeImage(os, null, fileFormat); + } + + public void writeImage(OutputStream os, String metadata, FileFormat fileFormat) throws IOException { + if (fileFormat == FileFormat.PNG) { + final BufferedImage im = createImage(); + PngIO.write(im, os, metadata); + } else if (fileFormat == FileFormat.SVG || fileFormat == FileFormat.EPS_VIA_SVG) { + final UGraphicSvg svg = new UGraphicSvg(HtmlColor.getAsHtml(background), false); + drawU(svg); + svg.createXml(os); + } else if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { + final UGraphicTxt txt = new UGraphicTxt(); + drawU(txt); + txt.getCharArea().print(new PrintStream(os)); + } else { + throw new UnsupportedOperationException(); + } + } + + private BufferedImage createImage() { + EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, background); + // BufferedImage im = builder.getBufferedImage(); + Graphics2D g2d = builder.getGraphics2D(); + + final Dimension2D size = drawU(new UGraphicG2d(g2d, null)); + g2d.dispose(); + + builder = new EmptyImageBuilder((int) size.getWidth(), (int) size.getHeight(), background); + final BufferedImage im = builder.getBufferedImage(); + g2d = builder.getGraphics2D(); + if (disableTextAliasing) { + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + drawU(new UGraphicG2d(g2d, null)); + g2d.dispose(); + return im; + } + + public Dimension2D drawU(final UGraphic ug) { + final TextBlock textBlock = TextBlockUtils.create(strings, font, green, HorizontalAlignement.LEFT); + Dimension2D size = textBlock.calculateDimension(ug.getStringBounder()); + textBlock.drawU(ug, 0, 0); + + if (image != null) { + if (position == GraphicPosition.BOTTOM) { + ug.draw((size.getWidth() - image.getWidth()) / 2, size.getHeight(), new UImage(image)); + size = new Dimension2DDouble(size.getWidth(), size.getHeight() + image.getHeight()); + } else if (position == GraphicPosition.BACKGROUND_CORNER) { + ug.draw(size.getWidth() - image.getWidth(), size.getHeight() - image.getHeight(), new UImage(image)); + } + } + return size; + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/HorizontalAlignement.java b/src/net/sourceforge/plantuml/graphic/HorizontalAlignement.java new file mode 100644 index 000000000..1012b815e --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/HorizontalAlignement.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +public enum HorizontalAlignement { + + LEFT, CENTER, RIGHT + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/HtmlColor.java b/src/net/sourceforge/plantuml/graphic/HtmlColor.java new file mode 100644 index 000000000..6871c69f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/HtmlColor.java @@ -0,0 +1,288 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5204 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import net.sourceforge.plantuml.ugraphic.ColorChangerMonochrome; + +public class HtmlColor { + + private static final Map htmlNames; + private static final Set names; + + static { + // Taken from http://perl.wikipedia.com/wiki/Named_colors ? + htmlNames = new HashMap(); + names = new TreeSet(); + register("AliceBlue", "#F0F8FF"); + register("AntiqueWhite", "#FAEBD7"); + register("Aqua", "#00FFFF"); + register("Aquamarine", "#7FFFD4"); + register("Azure", "#F0FFFF"); + register("Beige", "#F5F5DC"); + register("Bisque", "#FFE4C4"); + register("Black", "#000000"); + register("BlanchedAlmond", "#FFEBCD"); + register("Blue", "#0000FF"); + register("BlueViolet", "#8A2BE2"); + register("Brown", "#A52A2A"); + register("BurlyWood", "#DEB887"); + register("CadetBlue", "#5F9EA0"); + register("Chartreuse", "#7FFF00"); + register("Chocolate", "#D2691E"); + register("Coral", "#FF7F50"); + register("CornflowerBlue", "#6495ED"); + register("Cornsilk", "#FFF8DC"); + register("Crimson", "#DC143C"); + register("Cyan", "#00FFFF"); + register("DarkBlue", "#00008B"); + register("DarkCyan", "#008B8B"); + register("DarkGoldenRod", "#B8860B"); + register("DarkGray", "#A9A9A9"); + register("DarkGreen", "#006400"); + register("DarkKhaki", "#BDB76B"); + register("DarkMagenta", "#8B008B"); + register("DarkOliveGreen", "#556B2F"); + register("Darkorange", "#FF8C00"); + register("DarkOrchid", "#9932CC"); + register("DarkRed", "#8B0000"); + register("DarkSalmon", "#E9967A"); + register("DarkSeaGreen", "#8FBC8F"); + register("DarkSlateBlue", "#483D8B"); + register("DarkSlateGray", "#2F4F4F"); + register("DarkTurquoise", "#00CED1"); + register("DarkViolet", "#9400D3"); + register("DeepPink", "#FF1493"); + register("DeepSkyBlue", "#00BFFF"); + register("DimGray", "#696969"); + register("DodgerBlue", "#1E90FF"); + register("FireBrick", "#B22222"); + register("FloralWhite", "#FFFAF0"); + register("ForestGreen", "#228B22"); + register("Fuchsia", "#FF00FF"); + register("Gainsboro", "#DCDCDC"); + register("GhostWhite", "#F8F8FF"); + register("Gold", "#FFD700"); + register("GoldenRod", "#DAA520"); + register("Gray", "#808080"); + register("Green", "#008000"); + register("GreenYellow", "#ADFF2F"); + register("HoneyDew", "#F0FFF0"); + register("HotPink", "#FF69B4"); + register("IndianRed", "#CD5C5C"); + register("Indigo", "#4B0082"); + register("Ivory", "#FFFFF0"); + register("Khaki", "#F0E68C"); + register("Lavender", "#E6E6FA"); + register("LavenderBlush", "#FFF0F5"); + register("LawnGreen", "#7CFC00"); + register("LemonChiffon", "#FFFACD"); + register("LightBlue", "#ADD8E6"); + register("LightCoral", "#F08080"); + register("LightCyan", "#E0FFFF"); + register("LightGoldenRodYellow", "#FAFAD2"); + register("LightGrey", "#D3D3D3"); + register("LightGreen", "#90EE90"); + register("LightPink", "#FFB6C1"); + register("LightSalmon", "#FFA07A"); + register("LightSeaGreen", "#20B2AA"); + register("LightSkyBlue", "#87CEFA"); + register("LightSlateGray", "#778899"); + register("LightSteelBlue", "#B0C4DE"); + register("LightYellow", "#FFFFE0"); + register("Lime", "#00FF00"); + register("LimeGreen", "#32CD32"); + register("Linen", "#FAF0E6"); + register("Magenta", "#FF00FF"); + register("Maroon", "#800000"); + register("MediumAquaMarine", "#66CDAA"); + register("MediumBlue", "#0000CD"); + register("MediumOrchid", "#BA55D3"); + register("MediumPurple", "#9370D8"); + register("MediumSeaGreen", "#3CB371"); + register("MediumSlateBlue", "#7B68EE"); + register("MediumSpringGreen", "#00FA9A"); + register("MediumTurquoise", "#48D1CC"); + register("MediumVioletRed", "#C71585"); + register("MidnightBlue", "#191970"); + register("MintCream", "#F5FFFA"); + register("MistyRose", "#FFE4E1"); + register("Moccasin", "#FFE4B5"); + register("NavajoWhite", "#FFDEAD"); + register("Navy", "#000080"); + register("OldLace", "#FDF5E6"); + register("Olive", "#808000"); + register("OliveDrab", "#6B8E23"); + register("Orange", "#FFA500"); + register("OrangeRed", "#FF4500"); + register("Orchid", "#DA70D6"); + register("PaleGoldenRod", "#EEE8AA"); + register("PaleGreen", "#98FB98"); + register("PaleTurquoise", "#AFEEEE"); + register("PaleVioletRed", "#D87093"); + register("PapayaWhip", "#FFEFD5"); + register("PeachPuff", "#FFDAB9"); + register("Peru", "#CD853F"); + register("Pink", "#FFC0CB"); + register("Plum", "#DDA0DD"); + register("PowderBlue", "#B0E0E6"); + register("Purple", "#800080"); + register("Red", "#FF0000"); + register("RosyBrown", "#BC8F8F"); + register("RoyalBlue", "#4169E1"); + register("SaddleBrown", "#8B4513"); + register("Salmon", "#FA8072"); + register("SandyBrown", "#F4A460"); + register("SeaGreen", "#2E8B57"); + register("SeaShell", "#FFF5EE"); + register("Sienna", "#A0522D"); + register("Silver", "#C0C0C0"); + register("SkyBlue", "#87CEEB"); + register("SlateBlue", "#6A5ACD"); + register("SlateGray", "#708090"); + register("Snow", "#FFFAFA"); + register("SpringGreen", "#00FF7F"); + register("SteelBlue", "#4682B4"); + register("Tan", "#D2B48C"); + register("Teal", "#008080"); + register("Thistle", "#D8BFD8"); + register("Tomato", "#FF6347"); + register("Turquoise", "#40E0D0"); + register("Violet", "#EE82EE"); + register("Wheat", "#F5DEB3"); + register("White", "#FFFFFF"); + register("WhiteSmoke", "#F5F5F5"); + register("Yellow", "#FFFF00"); + register("YellowGreen", "#9ACD32"); + } + + private static void register(String s, String color) { + htmlNames.put(s.toLowerCase(), color); + names.add(s); + } + + private final Color color; + + public HtmlColor(String s) { + if (s.matches("#[0-9A-Fa-f]{6}")) { + color = new Color(Integer.parseInt(s.substring(1), 16)); + } else { + s = removeFirstDieseAndToLowercase(s); + final String value = htmlNames.get(s); + if (value == null) { + throw new IllegalArgumentException(s); + } + color = new Color(Integer.parseInt(value.substring(1), 16)); + } + assert isValid(s); + } + + private HtmlColor(Color c) { + this.color = c; + } + + static public boolean isValid(String s) { + if (s.matches("#[0-9A-Fa-f]{6}")) { + return true; + } + s = removeFirstDieseAndToLowercase(s); + if (htmlNames.containsKey(s)) { + return true; + } + return false; + + } + + static public HtmlColor getColorIfValid(String s) { + if (s == null || isValid(s) == false) { + return null; + } + return new HtmlColor(s); + } + + public static String getAsHtml(Color color) { + if (color == null) { + throw new IllegalArgumentException(); + } + final int v = 0xFFFFFF & color.getRGB(); + String s = "000000" + Integer.toHexString(v).toUpperCase(); + s = s.substring(s.length() - 6); + return "#" + s; + } + + static private String removeFirstDieseAndToLowercase(String s) { + s = s.toLowerCase(); + if (s.startsWith("#")) { + s = s.substring(1); + } + return s; + } + + public String getAsHtml() { + return getAsHtml(getColor()); + } + + public Color getColor() { + if (forceMonochrome) { + return new ColorChangerMonochrome().getChangedColor(color); + } + return color; + } + + @Override + public String toString() { + return super.toString() + " " + getAsHtml(); + } + + private static boolean forceMonochrome = false; + + public static final boolean isForceMonochrome() { + return forceMonochrome; + } + + public static final void setForceMonochrome(boolean forceMonochrome) { + HtmlColor.forceMonochrome = forceMonochrome; + } + + public static Collection names() { + return Collections.unmodifiableSet(names); + } +} diff --git a/src/net/sourceforge/plantuml/graphic/HtmlCommand.java b/src/net/sourceforge/plantuml/graphic/HtmlCommand.java new file mode 100644 index 000000000..90154ed82 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/HtmlCommand.java @@ -0,0 +1,37 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +public interface HtmlCommand { +} diff --git a/src/net/sourceforge/plantuml/graphic/HtmlCommandFactory.java b/src/net/sourceforge/plantuml/graphic/HtmlCommandFactory.java new file mode 100644 index 000000000..d3166bf28 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/HtmlCommandFactory.java @@ -0,0 +1,105 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5506 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.util.EnumSet; +import java.util.regex.Pattern; + +class HtmlCommandFactory { + + static final Pattern addStyle; + static final Pattern removeStyle; + + static { + final StringBuilder sbAddStyle = new StringBuilder(); + final StringBuilder sbRemoveStyle = new StringBuilder(); + + for (FontStyle style : EnumSet.allOf(FontStyle.class)) { + if (style == FontStyle.PLAIN) { + continue; + } + if (sbAddStyle.length() > 0) { + sbAddStyle.append('|'); + sbRemoveStyle.append('|'); + } + sbAddStyle.append(style.getActivationPattern()); + sbRemoveStyle.append(style.getDeactivationPattern()); + } + + addStyle = Pattern.compile(sbAddStyle.toString(), Pattern.CASE_INSENSITIVE); + removeStyle = Pattern.compile(sbRemoveStyle.toString(), Pattern.CASE_INSENSITIVE); + } + + private Pattern htmlTag = Pattern.compile(Splitter.htmlTag, Pattern.CASE_INSENSITIVE); + + HtmlCommand getHtmlCommand(String s) { + if (htmlTag.matcher(s).matches() == false) { + return new Text(s); + } + if (s.matches(Splitter.imgPattern)) { + return Img.getInstance(s); + } + + if (s.matches(Splitter.imgPattern2)) { + return Img.getInstance2(s); + } + + if (addStyle.matcher(s).matches()) { + //return new AddStyle(FontStyle.getStyle(s)); + return new AddStyle(s); + } + if (removeStyle.matcher(s).matches()) { + return new RemoveStyle(FontStyle.getStyle(s)); + } + + if (s.matches(Splitter.fontPattern)) { + return new ColorAndSizeChange(s); + } + + if (s.matches(Splitter.fontColorPattern2)) { + return new ColorChange(s); + } + + if (s.matches(Splitter.fontSizePattern2)) { + return new SizeChange(s); + } + + if (s.matches(Splitter.endFontPattern)) { + return new ResetFont(); + } + + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/Img.java b/src/net/sourceforge/plantuml/graphic/Img.java new file mode 100644 index 000000000..5032d4c78 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/Img.java @@ -0,0 +1,115 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5072 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.io.File; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.FileSystem; + +class Img implements HtmlCommand { + + final static private Pattern srcPattern = Pattern.compile("(?i)src\\s*=\\s*[\"']?([^ \">]+)[\"']?"); + final static private Pattern vspacePattern = Pattern.compile("(?i)vspace\\s*=\\s*[\"']?(\\d+)[\"']?"); + final static private Pattern valignPattern = Pattern.compile("(?i)valign\\s*=\\s*[\"']?(top|bottom|middle)[\"']?"); + final static private Pattern srcPattern2 = Pattern.compile("(?i)" + Splitter.imgPattern2); + + private final TileImage tileImage; + + private Img(TileImage image) throws IOException { + this.tileImage = image; + } + + static int getVspace(String html) { + final Matcher m = vspacePattern.matcher(html); + if (m.find() == false) { + return 0; + } + return Integer.parseInt(m.group(1)); + } + + static ImgValign getValign(String html) { + final Matcher m = valignPattern.matcher(html); + if (m.find() == false) { + return ImgValign.TOP; + } + return ImgValign.valueOf(m.group(1).toUpperCase()); + } + + static HtmlCommand getInstance(String html) { + final Matcher m = srcPattern.matcher(html); + if (m.find() == false) { + return new Text("(SYNTAX ERROR)"); + } + final String src = m.group(1); + try { + final File f = FileSystem.getInstance().getFile(src); + if (f.exists() == false) { + return new Text("(File not found: " + f + ")"); + } + + final int vspace = getVspace(html); + final ImgValign valign = getValign(html); + return new Img(new TileImage(ImageIO.read(f), valign, vspace)); + } catch (IOException e) { + return new Text("ERROR " + e.toString()); + } + } + + static HtmlCommand getInstance2(String html) { + final Matcher m = srcPattern2.matcher(html); + if (m.find() == false) { + return new Text("(SYNTAX ERROR)"); + } + final String src = m.group(1); + try { + final File f = FileSystem.getInstance().getFile(src); + if (f.exists() == false) { + return new Text("(File not found: " + f + ")"); + } + + return new Img(new TileImage(ImageIO.read(f), ImgValign.TOP, 0)); + } catch (IOException e) { + return new Text("ERROR " + e.toString()); + } + } + + public TileImage createMonoImage() { + return tileImage; + } +} diff --git a/src/net/sourceforge/plantuml/graphic/ImgValign.java b/src/net/sourceforge/plantuml/graphic/ImgValign.java new file mode 100644 index 000000000..dc9ac5dc3 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/ImgValign.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +enum ImgValign { + TOP, BOTTOM, MIDDLE +} diff --git a/src/net/sourceforge/plantuml/graphic/Line.java b/src/net/sourceforge/plantuml/graphic/Line.java new file mode 100644 index 000000000..cc3e44bb5 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/Line.java @@ -0,0 +1,51 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.ugraphic.UGraphic; + +interface Line { + + Dimension2D calculateDimension(StringBounder stringBounder); + + void draw(Graphics2D g2d, double x, double y); + + void drawU(UGraphic ug, double x, double y); + + HorizontalAlignement getHorizontalAlignement(); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/RemoveStyle.java b/src/net/sourceforge/plantuml/graphic/RemoveStyle.java new file mode 100644 index 000000000..089288eef --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/RemoveStyle.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +class RemoveStyle implements FontChange { + + private final FontStyle style; + + RemoveStyle(FontStyle style) { + this.style = style; + } + + public FontConfiguration apply(FontConfiguration initial) { + return initial.remove(style); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/ResetFont.java b/src/net/sourceforge/plantuml/graphic/ResetFont.java new file mode 100644 index 000000000..fdee2a7c4 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/ResetFont.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +class ResetFont implements FontChange { + + public FontConfiguration apply(FontConfiguration initial) { + return initial.resetFont(); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/SingleLine.java b/src/net/sourceforge/plantuml/graphic/SingleLine.java new file mode 100644 index 000000000..30765baf7 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/SingleLine.java @@ -0,0 +1,135 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class SingleLine implements Line { + + private final List blocs = new ArrayList(); + private final HorizontalAlignement horizontalAlignement; + + public SingleLine(String text, Font font, Color paint, HorizontalAlignement horizontalAlignement) { + this.horizontalAlignement = horizontalAlignement; + final Splitter lineSplitter = new Splitter(text); + + FontConfiguration fontConfiguration = new FontConfiguration(font, paint); + + for (HtmlCommand cmd : lineSplitter.getHtmlCommands()) { + if (cmd instanceof Text) { + final String s = ((Text) cmd).getText(); + blocs.add(new TileText(s, fontConfiguration)); + } else if (cmd instanceof Img) { + blocs.add(((Img) cmd).createMonoImage()); + } else if (cmd instanceof FontChange) { + fontConfiguration = ((FontChange) cmd).apply(fontConfiguration); + } + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + double width = 0; + double height = 0; + for (Tile b : blocs) { + final Dimension2D size2D = b.calculateDimension(stringBounder); + width += size2D.getWidth(); + height = Math.max(height, size2D.getHeight()); + } + return new Dimension2DDouble(width, height); + } + + private double maxDeltaY(Graphics2D g2d) { + double result = 0; + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d)); + for (Tile b : blocs) { + if (b instanceof TileText == false) { + continue; + } + final Dimension2D dimBloc = b.calculateDimension(StringBounderUtils.asStringBounder(g2d)); + final double deltaY = dim.getHeight() - dimBloc.getHeight() + ((TileText) b).getFontSize2D(); + result = Math.max(result, deltaY); + } + return result; + } + + private double maxDeltaY(UGraphic ug) { + double result = 0; + final Dimension2D dim = calculateDimension(ug.getStringBounder()); + for (Tile b : blocs) { + if (b instanceof TileText == false) { + continue; + } + final Dimension2D dimBloc = b.calculateDimension(ug.getStringBounder()); + final double deltaY = dim.getHeight() - dimBloc.getHeight() + ((TileText) b).getFontSize2D(); + result = Math.max(result, deltaY); + } + return result; + } + + public void draw(Graphics2D g2d, double x, double y) { + final double deltaY = maxDeltaY(g2d); + for (Tile b : blocs) { + if (b instanceof TileImage) { + b.draw(g2d, x, y); + } else { + b.draw(g2d, x, y + deltaY); + } + x += b.calculateDimension(StringBounderUtils.asStringBounder(g2d)).getWidth(); + } + } + + public void drawU(UGraphic ug, double x, double y) { + final double deltaY = maxDeltaY(ug); + for (Tile b : blocs) { + if (b instanceof TileImage) { + b.drawU(ug, x, y); + } else { + b.drawU(ug, x, y + deltaY); + } + x += b.calculateDimension(ug.getStringBounder()).getWidth(); + } + } + + public HorizontalAlignement getHorizontalAlignement() { + return horizontalAlignement; + } +} diff --git a/src/net/sourceforge/plantuml/graphic/SizeChange.java b/src/net/sourceforge/plantuml/graphic/SizeChange.java new file mode 100644 index 000000000..17a665b0c --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/SizeChange.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class SizeChange implements FontChange { + + static private final Pattern sizePattern = Pattern.compile("(?i)" + Splitter.fontSizePattern2); + + private final Integer size; + + SizeChange(String s) { + final Matcher matcherSize = sizePattern.matcher(s); + if (matcherSize.find() == false) { + throw new IllegalArgumentException(); + } + size = new Integer(matcherSize.group(1)); + } + + Integer getSize() { + return size; + } + + public FontConfiguration apply(FontConfiguration initial) { + return initial.changeSize(size); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/Splitter.java b/src/net/sourceforge/plantuml/graphic/Splitter.java new file mode 100644 index 000000000..65ac021fe --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/Splitter.java @@ -0,0 +1,110 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5072 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.StringUtils; + +public class Splitter { + + static final String endFontPattern = "\\|\\|\\"; + static final String fontPattern = "\\"; + static final String fontColorPattern2 = "\\"; + static final String fontSizePattern2 = "\\"; + static final String imgPattern = "]+['\"]?\\s*|vspace\\s*=\\s*['\"]?\\d+['\"]?\\s*|valign\\s*=\\s*['\"]?(top|middle|bottom)['\"]?\\s*)+>"; + static final String imgPattern2 = "]+)/?>"; + static final String htmlTag; + + private static final Pattern tagOrText; + + static { + final StringBuilder sb = new StringBuilder("(?i)"); + + for (FontStyle style : EnumSet.allOf(FontStyle.class)) { + if (style == FontStyle.PLAIN) { + continue; + } + sb.append(style.getActivationPattern()); + sb.append('|'); + sb.append(style.getDeactivationPattern()); + sb.append('|'); + } + sb.append(fontPattern); + sb.append('|'); + sb.append(fontColorPattern2); + sb.append('|'); + sb.append(fontSizePattern2); + sb.append('|'); + sb.append(endFontPattern); + sb.append('|'); + sb.append(imgPattern); + sb.append('|'); + sb.append(imgPattern2); + + htmlTag = sb.toString(); + tagOrText = Pattern.compile(htmlTag + "|.+?(?=" + htmlTag + ")|.+$", + Pattern.CASE_INSENSITIVE); + } + + private final List splitted = new ArrayList(); + + public Splitter(String s) { + final Matcher matcher = tagOrText.matcher(s); + while (matcher.find()) { + String part = matcher.group(0); + part = StringUtils.showComparatorCharacters(part); + splitted.add(part); + } + } + + List getSplittedInternal() { + return splitted; + } + + public List getHtmlCommands() { + final HtmlCommandFactory factory = new HtmlCommandFactory(); + final List result = new ArrayList(); + for (String s : getSplittedInternal()) { + result.add(factory.getHtmlCommand(s)); + } + return Collections.unmodifiableList(result); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/StringBounder.java b/src/net/sourceforge/plantuml/graphic/StringBounder.java new file mode 100644 index 000000000..38eb39f70 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/StringBounder.java @@ -0,0 +1,43 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4987 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Font; +import java.awt.geom.Dimension2D; + +public interface StringBounder { + + public Dimension2D calculateDimension(Font font, String text); + +} diff --git a/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java b/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java new file mode 100644 index 000000000..bfdb4d4d8 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/StringBounderUtils.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4110 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.Dimension2DDouble; + +public class StringBounderUtils { + + public static StringBounder asStringBounder(final Graphics2D g2d) { + + return new StringBounder() { + public Dimension2D calculateDimension(Font font, String text) { + final FontMetrics fm = g2d.getFontMetrics(font); + final Rectangle2D rect = fm.getStringBounds(text, g2d); + return new Dimension2DDouble(rect.getWidth(), rect.getHeight()); + } + + public double getFontDescent(Font font) { + final FontMetrics fm = g2d.getFontMetrics(font); + return fm.getDescent(); + } + + public double getFontAscent(Font font) { + final FontMetrics fm = g2d.getFontMetrics(font); + return fm.getAscent(); + } + +// public UnusedSpace getUnusedSpace(Font font, char c) { +// //return new UnusedSpace(7, 6, 0, 2); +// return new UnusedSpace(font, c); +// } + }; + } +} diff --git a/src/net/sourceforge/plantuml/graphic/Text.java b/src/net/sourceforge/plantuml/graphic/Text.java new file mode 100644 index 000000000..e80ea7682 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/Text.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +public class Text implements HtmlCommand { + + private final String text; + + Text(String text) { + this.text = text; + } + + public String getText() { + return text; + } +} diff --git a/src/net/sourceforge/plantuml/graphic/TextBlock.java b/src/net/sourceforge/plantuml/graphic/TextBlock.java new file mode 100644 index 000000000..427a72da2 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlock.java @@ -0,0 +1,49 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public interface TextBlock { + + Dimension2D calculateDimension(StringBounder stringBounder); + + void drawTOBEREMOVED(Graphics2D g2d, double x, double y); + + void drawU(UGraphic ug, double x, double y); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java b/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java new file mode 100644 index 000000000..a60e9fa41 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlockSimple.java @@ -0,0 +1,115 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class TextBlockSimple implements TextBlock { + + private final List lines = new ArrayList(); + + protected TextBlockSimple(List texts, Font font, Color paint, + HorizontalAlignement horizontalAlignement) { + for (CharSequence s : texts) { + if (s instanceof Stereotype) { + lines.add(createLineForStereotype(font, paint, (Stereotype) s, horizontalAlignement)); + } else { + lines.add(new SingleLine(s.toString(), font, paint, horizontalAlignement)); + } + } + } + + private SingleLine createLineForStereotype(Font font, Color paint, Stereotype s, + HorizontalAlignement horizontalAlignement) { + assert s.getLabel() != null; + return new SingleLine(s.getLabel(), font.deriveFont(Font.ITALIC), paint, horizontalAlignement); + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return getTextDimension(stringBounder); + } + + protected final Dimension2D getTextDimension(StringBounder stringBounder) { + double width = 0; + double height = 0; + for (Line line : lines) { + final Dimension2D size2D = line.calculateDimension(stringBounder); + height += size2D.getHeight(); + width = Math.max(width, size2D.getWidth()); + } + return new Dimension2DDouble(width, height); + } + + public void drawTOBEREMOVED(Graphics2D g2d, double x, double y) { + final Dimension2D dimText = getTextDimension(StringBounderUtils.asStringBounder(g2d)); + + for (Line line : lines) { + final HorizontalAlignement lineHorizontalAlignement = line.getHorizontalAlignement(); + double deltaX = 0; + if (lineHorizontalAlignement == HorizontalAlignement.CENTER) { + final double diff = dimText.getWidth() + - line.calculateDimension(StringBounderUtils.asStringBounder(g2d)).getWidth(); + deltaX = diff / 2.0; + } + line.draw(g2d, x + deltaX, y); + y += line.calculateDimension(StringBounderUtils.asStringBounder(g2d)).getHeight(); + } + } + + public void drawU(UGraphic ug, double x, double y) { + final Dimension2D dimText = getTextDimension(ug.getStringBounder()); + + for (Line line : lines) { + final HorizontalAlignement lineHorizontalAlignement = line.getHorizontalAlignement(); + double deltaX = 0; + if (lineHorizontalAlignement == HorizontalAlignement.CENTER) { + final double diff = dimText.getWidth() + - line.calculateDimension(ug.getStringBounder()).getWidth(); + deltaX = diff / 2.0; + } + line.drawU(ug, x + deltaX, y); + y += line.calculateDimension(ug.getStringBounder()).getHeight(); + } + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockSpotted.java b/src/net/sourceforge/plantuml/graphic/TextBlockSpotted.java new file mode 100644 index 000000000..c7e285f92 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlockSpotted.java @@ -0,0 +1,112 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class TextBlockSpotted extends TextBlockSimple { + + private final CircledCharacter circledCharacter; + + public TextBlockSpotted(CircledCharacter circledCharacter, List texts, Font font, + Color paint, HorizontalAlignement horizontalAlignement) { + super(texts, font, paint, horizontalAlignement); + this.circledCharacter = circledCharacter; + } + + @Override + public Dimension2D calculateDimension(StringBounder stringBounder) { + final double widthCircledCharacter = getCircledCharacterWithAndMargin(stringBounder); + final double heightCircledCharacter = circledCharacter.getPreferredHeight(stringBounder); + + final Dimension2D dim = super.calculateDimension(stringBounder); + return new Dimension2DDouble(dim.getWidth() + widthCircledCharacter, Math.max(heightCircledCharacter, dim + .getHeight())); + } + + private double getCircledCharacterWithAndMargin(StringBounder stringBounder) { + return circledCharacter.getPreferredWidth(stringBounder) + 6.0; + } + + @Override + public void drawTOBEREMOVED(Graphics2D g2d, double x, double y) { +// final AffineTransform at = g2d.getTransform(); +// final StringBounder stringBounder = StringBounderUtils.asStringBounder(g2d); +// +// final double deltaY = calculateDimension(StringBounderUtils.asStringBounder(g2d)).getHeight() +// - circledCharacter.getPreferredHeight(stringBounder); +// +// // g2d.translate(x, y + deltaY / 2.0); +// circledCharacter.draw(g2d, (int) x, (int) (y + deltaY / 2.0)); +// // circledCharacter.draw(g2d); +// +// g2d.setTransform(at); +// final double widthCircledCharacter = getCircledCharacterWithAndMargin(stringBounder); +// g2d.translate(widthCircledCharacter, 0); +// +// super.drawTOBEREMOVED(g2d, x, y); +// +// g2d.setTransform(at); + throw new UnsupportedOperationException(); + } + + @Override + public void drawU(UGraphic ug, double x, double y) { + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + final StringBounder stringBounder = ug.getStringBounder(); + +// final double deltaY = calculateDimension(stringBounder).getHeight() +// - circledCharacter.getPreferredHeight(stringBounder); + + //circledCharacter.drawU(ug, (int) x, (int) (y + deltaY / 2.0)); + circledCharacter.drawU(ug, x, y); + + ug.setTranslate(atX, atY); + final double widthCircledCharacter = getCircledCharacterWithAndMargin(stringBounder); + ug.translate(widthCircledCharacter, 0); + + super.drawU(ug, x, y); + + ug.setTranslate(atX, atY); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java new file mode 100644 index 000000000..955f78a70 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlockUtils.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4111 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.util.List; + +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.sequencediagram.MessageNumber; + +public class TextBlockUtils { + + public static TextBlock create(List texts, Font font, Color paint, + HorizontalAlignement horizontalAlignement) { + if (texts.size() > 0 && texts.get(0) instanceof Stereotype) { + return createStereotype(texts, font, paint, horizontalAlignement); + } + if (texts.size() > 0 && texts.get(0) instanceof MessageNumber) { + return createMessageNumber(texts, font, paint, horizontalAlignement); + } + return new TextBlockSimple(texts, font, paint, horizontalAlignement); + } + + private static TextBlock createMessageNumber(List texts, Font font, Color paint, + HorizontalAlignement horizontalAlignement) { + final MessageNumber number = (MessageNumber) texts.get(0); + return new TextBlockWithNumber(number.getNumber(), texts.subList(1, texts.size()), font, paint, + horizontalAlignement); + + } + + private static TextBlock createStereotype(List texts, Font font, Color paint, + HorizontalAlignement horizontalAlignement) { + final Stereotype stereotype = (Stereotype) texts.get(0); + if (stereotype.isSpotted()) { + final CircledCharacter circledCharacter = new CircledCharacter(stereotype.getCharacter(), stereotype + .getRadius(), stereotype.getCircledFont(), stereotype.getColor(), null, paint); + if (stereotype.getLabel() == null) { + return new TextBlockSpotted(circledCharacter, texts.subList(1, texts.size()), font, paint, + horizontalAlignement); + } + return new TextBlockSpotted(circledCharacter, texts, font, paint, horizontalAlignement); + } + return new TextBlockSimple(texts, font, paint, horizontalAlignement); + } + + // static private Font deriveForCircleCharacter(Font font) { + // final float size = font.getSize2D(); + // return font.deriveFont(size - 1).deriveFont(Font.BOLD); + // } + +} diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockWithNumber.java b/src/net/sourceforge/plantuml/graphic/TextBlockWithNumber.java new file mode 100644 index 000000000..7a90c16a9 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlockWithNumber.java @@ -0,0 +1,92 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class TextBlockWithNumber extends TextBlockSimple { + + private final TextBlock numText; + + public TextBlockWithNumber(String number, List texts, Font font, Color paint, + HorizontalAlignement horizontalAlignement) { + super(texts, font, paint, horizontalAlignement); + this.numText = TextBlockUtils.create(Arrays.asList(number), font, paint, HorizontalAlignement.LEFT); + } + + @Override + public Dimension2D calculateDimension(StringBounder stringBounder) { + final double widthNum = getNumberWithAndMargin(stringBounder); + final double heightNum = numText.calculateDimension(stringBounder).getHeight(); + + final Dimension2D dim = super.calculateDimension(stringBounder); + return new Dimension2DDouble(dim.getWidth() + widthNum, Math.max(heightNum, dim.getHeight())); + } + + private double getNumberWithAndMargin(StringBounder stringBounder) { + final double widthNum = numText.calculateDimension(stringBounder).getWidth(); + return widthNum + 4.0; + } + + @Override + public void drawTOBEREMOVED(Graphics2D g2d, double x, double y) { + final StringBounder stringBounder = StringBounderUtils.asStringBounder(g2d); + final double heightNum = numText.calculateDimension(stringBounder).getHeight(); + + final double deltaY = calculateDimension(stringBounder).getHeight() - heightNum; + + numText.drawTOBEREMOVED(g2d, x, y + deltaY / 2.0); + super.drawTOBEREMOVED(g2d, x + getNumberWithAndMargin(stringBounder), y); + } + + @Override + public void drawU(UGraphic ug, double x, double y) { + final StringBounder stringBounder = ug.getStringBounder(); + final double heightNum = numText.calculateDimension(stringBounder).getHeight(); + + final double deltaY = calculateDimension(stringBounder).getHeight() - heightNum; + + numText.drawU(ug, x, y + deltaY / 2.0); + super.drawU(ug, x + getNumberWithAndMargin(stringBounder), y); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/Tile.java b/src/net/sourceforge/plantuml/graphic/Tile.java new file mode 100644 index 000000000..75684b789 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/Tile.java @@ -0,0 +1,49 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.ugraphic.UGraphic; + +interface Tile { + + Dimension2D calculateDimension(StringBounder stringBounder); + + void draw(Graphics2D g2d, double x, double y); + + void drawU(UGraphic ug, double x, double y); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/TileImage.java b/src/net/sourceforge/plantuml/graphic/TileImage.java new file mode 100644 index 000000000..a6af2bca6 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TileImage.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3932 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.image.BufferedImage; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UImage; + +class TileImage implements Tile { + + private final BufferedImage image; + private final int vspace; + + public TileImage(BufferedImage image, ImgValign valign, int vspace) { + this.image = image; + this.vspace = vspace; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return new Dimension2DDouble(image.getWidth(), image.getHeight() + 2 * vspace); + } + + public void draw(Graphics2D g2d, double x, double y) { + g2d.drawImage(image, (int) x, (int) y + vspace, null); + } + + public void drawU(UGraphic ug, double x, double y) { + ug.draw(x, y + vspace, new UImage(image)); + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/TileText.java b/src/net/sourceforge/plantuml/graphic/TileText.java new file mode 100644 index 000000000..e7065fc33 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TileText.java @@ -0,0 +1,101 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5507 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.BasicStroke; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UText; + +class TileText implements Tile { + + private final String text; + private final FontConfiguration fontConfiguration; + + public TileText(String text, FontConfiguration fontConfiguration) { + this.fontConfiguration = fontConfiguration; + this.text = text; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + final Dimension2D rect = stringBounder.calculateDimension(fontConfiguration.getFont(), text); + Log.debug("g2d=" + rect); + Log.debug("Size for " + text + " is " + rect); + double h = rect.getHeight(); + if (h < 10) { + h = 10; + } + return new Dimension2DDouble(rect.getWidth(), h); + } + + public double getFontSize2D() { + return fontConfiguration.getFont().getSize2D(); + } + + public void draw(Graphics2D g2d, double x, double y) { + // TO be removed + g2d.setFont(fontConfiguration.getFont()); + g2d.setPaint(fontConfiguration.getColor()); + g2d.drawString(text, (float) x, (float) y); + + if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) { + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d)); + final int ypos = (int) (y + 2.5); + g2d.setStroke(new BasicStroke((float) 1.3)); + g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos); + g2d.setStroke(new BasicStroke()); + } + if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d)); + final FontMetrics fm = g2d.getFontMetrics(fontConfiguration.getFont()); + final int ypos = (int) (y - fm.getDescent() - 0.5); + g2d.setStroke(new BasicStroke((float) 1.5)); + g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos); + g2d.setStroke(new BasicStroke()); + } + } + + public void drawU(UGraphic ug, double x, double y) { + final UText utext = new UText(text, fontConfiguration); + ug.getParam().setColor(fontConfiguration.getColor()); + ug.draw(x, y, utext); + + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/UnusedSpace.java b/src/net/sourceforge/plantuml/graphic/UnusedSpace.java new file mode 100644 index 000000000..265a09693 --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/UnusedSpace.java @@ -0,0 +1,171 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4107 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class UnusedSpace { + + static class Point { + final private double x; + final private double y; + + Point(double x, double y) { + this.x = x; + this.y = y; + } + + public double getDistSq(Point other) { + final double dx = this.x - other.x; + final double dy = this.y - other.y; + return dx * dx + dy * dy; + } + } + + private static final int HALF_SIZE = 20; + + private double meanX2; + private double meanY2; + + private final List points = new ArrayList(); + + final private static Map cache = new HashMap(); + + public static UnusedSpace getUnusedSpace(Font font, char c) { + final Object key = Arrays.asList(font, c); + UnusedSpace result = cache.get(key); + if (result == null) { + result = new UnusedSpace(font, c); + cache.put(key, result); + } + return result; + } + + private UnusedSpace(Font font, char c) { + final BufferedImage im = new BufferedImage(2 * HALF_SIZE, 2 * HALF_SIZE, BufferedImage.TYPE_INT_RGB); + final Graphics2D g2d = im.createGraphics(); + g2d.setFont(font); + g2d.drawString("" + c, HALF_SIZE, HALF_SIZE); + + int minI = Integer.MAX_VALUE; + int minJ = Integer.MAX_VALUE; + int maxI = Integer.MIN_VALUE; + int maxJ = Integer.MIN_VALUE; + + for (int i = 0; i < im.getWidth(); i++) { + for (int j = 0; j < im.getHeight(); j++) { + if (isPoint(im, i, j)) { + if (i < minI) { + minI = i; + } + if (j < minJ) { + minJ = j; + } + if (i > maxI) { + maxI = i; + } + if (j > maxJ) { + maxJ = j; + } + points.add(new Point(i, j)); + } + } + } + + double min = Double.MAX_VALUE; + for (int i = minI * 4; i <= maxI * 4; i++) { + for (int j = minJ * 4; j < maxJ * 4; j++) { + final Point p = new Point(i / 4.0, j / 4.0); + final double d = biggestDistSqFromPoint(p); + if (d < min) { + min = d; + this.meanX2 = i / 4.0 - HALF_SIZE; + this.meanY2 = j / 4.0 - HALF_SIZE; + } + } + } + + // g2d.setColor(Color.RED); + // g2d.draw(new Line2D.Double(meanX2 + HALF_SIZE - 1, meanY2 + HALF_SIZE + // - 1, meanX2 + HALF_SIZE + 1, meanY2 + // + HALF_SIZE + 1)); + // g2d.draw(new Line2D.Double(meanX2 + HALF_SIZE + 1, meanY2 + HALF_SIZE + // - 1, meanX2 + HALF_SIZE - 1, meanY2 + // + HALF_SIZE + 1)); + + // int cpt = 1; + // try { + // ImageIO.write(im, "png", new File("c:/img" + cpt + ".png")); + // cpt++; + // } catch (IOException e) { + // e.printStackTrace(); + // } + + } + + private double biggestDistSqFromPoint(Point p) { + double result = 0; + for (Point other : points) { + final double d = p.getDistSq(other); + if (d > result) { + result = d; + } + } + return result; + } + + private static boolean isPoint(BufferedImage im, int x, int y) { + final int color = im.getRGB(x, y) & 0x00FFFFFF; + if (color == 0) { + return false; + } + return true; + } + + public double getCenterX() { + return meanX2; + } + + public double getCenterY() { + return meanY2; + } + +} diff --git a/src/net/sourceforge/plantuml/graphic/VerticalPosition.java b/src/net/sourceforge/plantuml/graphic/VerticalPosition.java new file mode 100644 index 000000000..c5da11e9e --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/VerticalPosition.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3834 $ + * + */ +package net.sourceforge.plantuml.graphic; + +public enum VerticalPosition { + + TOP, BOTTOM + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java b/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java new file mode 100644 index 000000000..5838b55c9 --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java @@ -0,0 +1,88 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4159 $ + * + */ +package net.sourceforge.plantuml.objectdiagram; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; + +public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram { + + final public boolean insertBetween(IEntity entity1, IEntity entity2, IEntity node) { + final Link link = foundLink(entity1, entity2); + if (link == null) { + return false; + } + final Link l1 = new Link(entity1, node, link.getType(), link.getLabel(), link.getLength(), + link.getQualifier1(), null, link.getLabeldistance(), link.getLabelangle()); + final Link l2 = new Link(node, entity2, link.getType(), link.getLabel(), link.getLength(), null, link + .getQualifier2(), link.getLabeldistance(), link.getLabelangle()); + addLink(l1); + addLink(l2); + removeLink(link); + return true; + } + + private Link foundLink(IEntity entity1, IEntity entity2) { + Link result = null; + final List links = getLinks(); + for (int i = links.size() - 1; i >= 0; i--) { + final Link l = links.get(i); + if (l.isBetween(entity1, entity2)) { + if (result != null) { + return null; + } + result = l; + } + } + return result; + } + + public int getNbOfHozizontalLollipop(IEntity entity) { + if (entity.getType() == EntityType.LOLLIPOP) { + throw new IllegalArgumentException(); + } + int result = 0; + for (Link link : getLinks()) { + if (link.getLength() == 1 && link.contains(entity) && link.containsType(EntityType.LOLLIPOP)) { + result++; + } + + } + return result; + } +} diff --git a/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagram.java b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagram.java new file mode 100644 index 000000000..e928842ed --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagram.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4159 $ + * + */ +package net.sourceforge.plantuml.objectdiagram; + +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class ObjectDiagram extends AbstractClassOrObjectDiagram { + + @Override + public IEntity getOrCreateClass(String code) { + return getOrCreateEntity(code, EntityType.OBJECT); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.OBJECT; + } + +} diff --git a/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java new file mode 100644 index 000000000..c9a2fea71 --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4192 $ + * + */ +package net.sourceforge.plantuml.objectdiagram; + +import net.sourceforge.plantuml.classdiagram.command.CommandLinkClass; +import net.sourceforge.plantuml.classdiagram.command.CommandMultilinesClassNote; +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.command.CommandCreateNote; +import net.sourceforge.plantuml.command.CommandEndPackage; +import net.sourceforge.plantuml.command.CommandMultilinesStandaloneNote; +import net.sourceforge.plantuml.command.CommandNoteEntity; +import net.sourceforge.plantuml.command.CommandPackage; +import net.sourceforge.plantuml.command.CommandPage; +import net.sourceforge.plantuml.objectdiagram.command.CommandAddData; +import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObject; +import net.sourceforge.plantuml.objectdiagram.command.CommandCreateEntityObjectMultilines; + +public class ObjectDiagramFactory extends AbstractUmlSystemCommandFactory { + + private ObjectDiagram system; + + public ObjectDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new ObjectDiagram(); + + addCommonCommands(system); + + addCommand(new CommandPage(system)); + addCommand(new CommandAddData(system)); + addCommand(new CommandLinkClass(system)); + // + addCommand(new CommandCreateEntityObject(system)); + addCommand(new CommandCreateNote(system)); + addCommand(new CommandPackage(system)); + addCommand(new CommandEndPackage(system)); + // addCommand(new CommandNamespace(system)); + // addCommand(new CommandEndNamespace(system)); + // addCommand(new CommandStereotype(system)); + // + // addCommand(new CommandImport(system)); + addCommand(new CommandNoteEntity(system)); + + addCommand(new CommandMultilinesClassNote(system)); + addCommand(new CommandMultilinesStandaloneNote(system)); + addCommand(new CommandCreateEntityObjectMultilines(system)); + + // addCommand(new CommandNoopClass(system)); + + } +} diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandAddData.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandAddData.java new file mode 100644 index 000000000..363e6baad --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandAddData.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4546 $ + * + */ +package net.sourceforge.plantuml.objectdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.objectdiagram.ObjectDiagram; +import net.sourceforge.plantuml.skin.VisibilityModifier; + +public class CommandAddData extends SingleLineCommand { + + public CommandAddData(ObjectDiagram diagram) { + super(diagram, "(?i)^([\\p{L}0-9_.]+)\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Entity entity = (Entity) getSystem().getOrCreateClass(arg.get(0)); + + final String field = arg.get(1); + if (field.length() > 0 && VisibilityModifier.isVisibilityCharacter(field.charAt(0))) { + getSystem().setVisibilityModifierPresent(true); + } + entity.addField(field); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java new file mode 100644 index 000000000..01d70d8c2 --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4161 $ + * + */ +package net.sourceforge.plantuml.objectdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.objectdiagram.ObjectDiagram; + +public class CommandCreateEntityObject extends SingleLineCommand { + + public CommandCreateEntityObject(ObjectDiagram diagram) { + super(diagram, + "(?i)^(object)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(2); + final String display = arg.get(1); + final String stereotype = arg.get(3); + if (getSystem().entityExist(code)) { + return CommandExecutionResult.error("Object already exists : "+code); + } + final Entity entity = getSystem().createEntity(code, display, EntityType.OBJECT); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java new file mode 100644 index 000000000..8ab3fb59b --- /dev/null +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4161 $ + * + */ +package net.sourceforge.plantuml.objectdiagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.objectdiagram.ObjectDiagram; +import net.sourceforge.plantuml.skin.VisibilityModifier; + +public class CommandCreateEntityObjectMultilines extends CommandMultilines { + + public CommandCreateEntityObjectMultilines(ObjectDiagram diagram) { + super( + diagram, + "(?i)^(object)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?\\s*\\{\\s*$", + "(?i)^\\s*\\}\\s*$"); + } + + public CommandExecutionResult execute(List lines) { + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final Entity entity = executeArg0(line0); + if (entity == null) { + return CommandExecutionResult.error("No such entity"); + } + for (String s : lines.subList(1, lines.size() - 1)) { + if (s.length() > 0 && VisibilityModifier.isVisibilityCharacter(s.charAt(0))) { + getSystem().setVisibilityModifierPresent(true); + } + entity.addField(s); + } + return CommandExecutionResult.ok(); + } + + private Entity executeArg0(List arg) { + final String code = arg.get(2); + final String display = arg.get(1); + final String stereotype = arg.get(3); + if (getSystem().entityExist(code)) { + return (Entity) getSystem().getOrCreateClass(code); + } + final Entity entity = getSystem().createEntity(code, display, EntityType.OBJECT); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return entity; + } + +} diff --git a/src/net/sourceforge/plantuml/oregon/BasicGame.java b/src/net/sourceforge/plantuml/oregon/BasicGame.java new file mode 100644 index 000000000..cd6ced83e --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/BasicGame.java @@ -0,0 +1,41 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +public interface BasicGame { + + void run(Keyboard keyboard) throws NoInputException; + + Screen getScreen(); +} diff --git a/src/net/sourceforge/plantuml/oregon/Keyboard.java b/src/net/sourceforge/plantuml/oregon/Keyboard.java new file mode 100644 index 000000000..b8c1cebcf --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/Keyboard.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +public interface Keyboard { + String input() throws NoInputException; + boolean hasMore(); + +} diff --git a/src/net/sourceforge/plantuml/oregon/KeyboardList.java b/src/net/sourceforge/plantuml/oregon/KeyboardList.java new file mode 100644 index 000000000..e06403e5c --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/KeyboardList.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +public class KeyboardList implements Keyboard { + + private final Iterator data; + + public KeyboardList(String... inputs) { + this(Arrays.asList(inputs)); + } + + public KeyboardList(Collection inputs) { + data = inputs.iterator(); + } + + + public String input() throws NoInputException { + if (data.hasNext()) { + return data.next(); + } + throw new NoInputException(); + } + + public boolean hasMore() { + return data.hasNext(); + } + +} diff --git a/src/net/sourceforge/plantuml/oregon/MagicTable.java b/src/net/sourceforge/plantuml/oregon/MagicTable.java new file mode 100644 index 000000000..e2b8cceeb --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/MagicTable.java @@ -0,0 +1,229 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +public class MagicTable { + + static enum Oc { + USED, NEAR + } + + private final Oc number[] = new Oc[10000]; + + private static ArrayList neighboors; + + static { + neighboors = new ArrayList(); + for (int i = 0; i < 10000; i++) { + neighboors.add(null); + } + } + + public static int[] getNeighboors(final int nb) { + if (neighboors.get(nb) == null) { + neighboors.set(nb, getNeighboorsSlow(nb)); + } + return neighboors.get(nb); + } + + public static int[] getNeighboorsSlow(final int nb) { + final int result[] = new int[36]; + + final int v1 = nb % 10; + int root = nb - v1; + int cpt = 0; + for (int i = 0; i < 10; i++) { + final int candidat = root + i; + if (candidat == nb) { + continue; + } + result[cpt++] = candidat; + } + final int v2 = (nb / 10) % 10; + root = nb - v2 * 10; + for (int i = 0; i < 10; i++) { + final int candidat = root + i * 10; + if (candidat == nb) { + continue; + } + result[cpt++] = candidat; + } + final int v3 = (nb / 100) % 10; + root = nb - v3 * 100; + for (int i = 0; i < 10; i++) { + final int candidat = root + i * 100; + if (candidat == nb) { + continue; + } + result[cpt++] = candidat; + } + final int v4 = nb / 1000; + root = nb - v4 * 1000; + for (int i = 0; i < 10; i++) { + final int candidat = root + i * 1000; + if (candidat == nb) { + continue; + } + result[cpt++] = candidat; + } + return result; + } + + public List getAllFree() { + final List result = new ArrayList(10000); + for (int i = 0; i < number.length; i++) { + if (number[i] == null) { + result.add(i); + } + } + return result; + } + + public List getAllUsed() { + final List result = new ArrayList(10000); + for (int i = 0; i < number.length; i++) { + if (number[i] == Oc.USED) { + result.add(i); + } + } + return result; + } + + public boolean isUsuable(int nb) { + if (number[nb] != null) { + return false; + } + for (int near : getNeighboors(nb)) { + if (number[near] != null) { + return false; + } + } + return true; + } + + public void burnNumber(int nb) { + if (number[nb] != null) { + throw new IllegalArgumentException(); + } + number[nb] = Oc.USED; + for (int near : getNeighboors(nb)) { + number[near] = Oc.NEAR; + } + } + + public int getRandomFree(Random rnd) { + final List frees = getAllFree(); + // final int size = frees.size(); + // for (int i = 0; i < size; i++) { + // final int pos = rnd.nextInt(frees.size()); + // final int nb = frees.get(pos); + // frees.remove(pos); + // if (isUsuable(nb)) { + // return nb; + // } + // } + Collections.shuffle(frees, rnd); + for (int nb : frees) { + if (isUsuable(nb)) { + return nb; + } + } + return -1; + + } + + public static int size(Random rnd, MagicTable mt) { + int i = 0; + while (true) { + final int candidat = mt.getRandomFree(rnd); + if (candidat == -1) { + break; + } + mt.burnNumber(candidat); + i++; + } + return i; + } + + public static void main(String[] args) { + int max = 0; + final long start = System.currentTimeMillis(); + final Random rnd = new Random(49); + final int nb = 200000; + for (int i = 0; i < nb; i++) { + if (i == 100) { + long dur = (System.currentTimeMillis() - start) / 1000L; + dur = dur * nb / 100; + dur = dur / 3600; + System.err.println("Estimated duration = " + dur + " h"); + } + final MagicTable mt = new MagicTable(); + final int v = MagicTable.size(rnd, mt); + if (v > max) { + System.err.println(v); + System.err.println(mt.getAllUsed()); + max = v; + } + } + final long duration = System.currentTimeMillis() - start; + System.err.println("Duration = " + duration / 1000L / 60); + + } + + public static void main2(String[] args) { + int max = 0; + final long start = System.currentTimeMillis(); + for (int j = 1; j < 100; j++) { + final Random rnd = new Random(j); + for (int i = 0; i < 1000; i++) { + final MagicTable mt = new MagicTable(); + final int v = MagicTable.size(rnd, mt); + if (v > max) { + System.err.println(v); + System.err.println(mt.getAllUsed()); + max = v; + } + } + } + final long duration = System.currentTimeMillis() - start; + System.err.println("Duration = " + duration / 1000L / 60); + + } + +} diff --git a/src/net/sourceforge/plantuml/oregon/NoInputException.java b/src/net/sourceforge/plantuml/oregon/NoInputException.java new file mode 100644 index 000000000..65011974a --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/NoInputException.java @@ -0,0 +1,37 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +public class NoInputException extends Exception { +} diff --git a/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java b/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java new file mode 100644 index 000000000..4c09e9349 --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/OregonBasicGame.java @@ -0,0 +1,916 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.util.Random; + +public class OregonBasicGame implements BasicGame { + + private Screen screen; + private SmartKeyboard skb; + private Random rnd; + + private int ks; + private int kh; + private int kp; + private int kb; + private int km; + private int kq; + + private double ma; + + + private final String da[] = new String[] { "March 29", "April 12", "April 26", "May 10", "May 24", "June 7", + "June 21", "July 5", "July 19", "August 2", "August 16", "August 31", "September 13", "September 27", + "October 11", "October 25", "November 8", "November 22", "December 6", "December 20" }; + + private final int ep[] = new int[] { 6, 11, 13, 15, 17, 22, 32, 35, 37, 42, 44, 54, 64, 69, 95 }; + + public Screen getScreen() { + return screen; + } + + private void print(String s) { + screen.print(s); + } + + private void printb(String s) { + screen.print("** " + s + " **"); + } + + private void print() { + screen.print(); + } + + public void run(Keyboard keyboard) throws NoInputException { + if (screen != null) { + throw new IllegalStateException(); + } + screen = new Screen(); + skb = new SmartKeyboard(keyboard); + init(); + } + + private double rnd() { + if (this.rnd == null) { + this.rnd = new Random(skb.getHistory().hashCode()); + } + return rnd.nextDouble(); + } + + private void init() throws NoInputException { + printInitialScenario490(); + initialPurchasesOfPlayer690(); + initialShootingRanking920(); + screen.clear(); + print("** Your trip is about to begin... **"); + print(); + for (int j = 0; j < 20; j++) { + if (m > 2039) { + madeIt3190(j); + break; + } + print("Monday, " + da[j] + ", 1847. You are " + whereAreWe()); + print(); + if (f < 6) { + print("** You're low on food. Better buy some or go hunting soon. **"); + print(); + } + if (ks == 1 || kh == 1) { + t = t - 10; + if (t < 0) { + needDoctorBadly3010(j); + } + print("Doctor charged $10 for his services"); + print("to treat your " + (ks == 1 ? "illness." : "injuries.")); + } + // MP flag to be done? + + m = (int) (m + .5); + print("Total mileage to date is: " + ((int) m) + ""); + m += 200 + (a - 110) / 2.5 + 10 * rnd(); + print(); + // Calculate how far we travel in 2 weeks + print("Here's what you now have (no. of bullets, $ worth of other items) :"); + printInventory3350(); + question1000(j); + eating1310(j); + screen.clear(); + riders1390(j); + // print(); + events1800(j); + // print(); + montains2640(j); + if (skb.hasMore()) { + screen.clear(); + } + } + } + + private void events1800(int j) throws NoInputException { + final int rn = (int) (100.0 * rnd()); + for (int i = 0; i < ep.length; i++) { + if (rn <= ep[i]) { + execEvent(i, j); + return; + } + } + execEvent(ep.length, j); + } + + private void execEvent(int i, int j) throws NoInputException { + switch (i) { + case 0: + printb("Your wagon breaks down. It costs you time and supplies to fix it."); + m = m - 15 - 5 * rnd(); + r = r - 4; + break; + case 1: + printb("An ox gores your leg. That slows you down for the rest of the trip."); + m = m - 25; + a = a - 10; + break; + case 2: + printb("Bad luck... your daughter breaks her arm. You must stop and"); + printb("make a splint and sling with some of your medical supplies."); + m = m - 5 - 4 * rnd(); + r = r - 1 - 2 * rnd(); + break; + case 3: + printb("An ox wanders off and you have to spend time looking for it."); + m = m - 17; + break; + case 4: + printb("Your son gets lost and you spend half a day searching for him."); + m = m - 10; + break; + case 5: + printb("Nothing but contaminated and stagnant water near the trail."); + printb("You lose time looking for a clean spring or creek."); + m = m - 2 - 10 * rnd(); + break; + + case 6: + if (m > 950) { + int c1 = 0; + if (c < 11 + 2 * rnd()) { + c1 = 1; + } + printb("Cold weather... Brrrrrrr! ... You " + (c1 == 1 ? "dont't " : "") + + "have enough clothing to keep warm."); + if (c1 == 1) { + dealWithIllness2880(j); + } + } else { + printb("Heavy rains. Traveling is slow in the mud and you break your spare"); + printb("ox yoke using it to pry your wagon out of the mud. Worse yet, some"); + printb("of your ammo is damaged by the water."); + m = m - 5 - 10 * rnd(); + r = r - 7; + b = b - 400; + f = f - 5; + } + break; + + case 7: + printb("Bandits attacking!"); + int br = shoot3870(); + b = b - 20 * br; + if (b > 0) { + if (br <= 1) { + print("That was the quickest draw outside of Dodge City."); + print("You got at least one and drove 'em off."); + return; + } + } else { + t = t / 3; + print("You try to drive them off but you run out of bullets."); + print("They grab as much cash as they can find."); + + } + print("You get shot in the leg -"); + kh = 1; + print("and they grab one of your oxen."); + a = a - 10; + r = r - 2; + print("Better have a doc look at your leg... and soon!"); + break; + + case 8: + printb("You have a fire in your wagon. Food and supplies are damaged."); + m = m - 15; + f = f - 20; + b = b - 400; + r = r - 2 * 6 * rnd(); + break; + + case 9: + printb("You lose your way in heavy fog. Time lost regaining the trail."); + m = m - 10 - 5 * rnd(); + break; + + case 10: + printb("You come upon a rattlesnake and before you are able to get your gun"); + printb("out, it bites you."); + b = b - 10; + r = r - 2; + if (r < 0) { + printb("You have no medical supplies left, and you die of poison."); + die3060(j); + + } + print("Fortunately, you acted quickly, sucked out the poison, and"); + print("treated the wound. It is painful, but you'll survive."); + break; + + case 11: + print("Your wagon gets swamped fording a river; you lose food and clothes."); + m = m - 20 - 20 * rnd(); + f = f - 15; + c = c - 10; + break; + + case 12: + printb("You're sound asleep and you hear a noise... get up to investigate."); + printb("It's wild animals! They attack you!"); + br = shoot3870(); + if (b <= 39) { + print("You're almost out of ammo; can't reach more."); + print("The wolves come at you biting and clawing."); + kh = 1; + die3030(j); + } + if (br <= 2) { + print("Nice shooting, pardner... They didn't get much."); + } else { + print("Kind of slow on the draw. The wolves got at your food and clothes."); + b = b - 20 * br; + c = c - 2 * br; + f = f - 4 * br; + } + break; + + case 13: + printb("You're caught in a fierce hailstorm; ammo and supplies are damaged."); + m = m - 5 - 10 * rnd(); + b = b - 150; + r = r - 2 - 2 * rnd(); + break; + + case 14: + if (e == 1) { + dealWithIllness2880(j); + } else if (e == 2 && rnd() > .25) { + dealWithIllness2880(j); + } else if (e == 3 && rnd() > .5) { + dealWithIllness2880(j); + } + break; + + case 15: + printb("Helpful Indians show you where to find more food."); + f = f + 7; + break; + + default: + printb("EVENT " + i); + } + print(); + + } + + private void madeIt3190(int j) throws NoInputException { + final double ml = (2040 - ma) / (m - ma); + f = f + (1 - ml) * (8 + 5 * e); + print("You finally arrived at Oregon City after 2040 long miles."); + print("You're exhausted and haggard, but you made it! A real pioneer!"); + final int d = (int) (14 * (j + ml)); + final int dm = (int) (d / 30.5); + final int dd = (int) (d - 30.5 * dm); + print("You've been on the trail for " + dm + " months and " + dd + " days."); + print("You have few supplies remaining :"); + printInventory3350(); + print(); + print("President James A. Polk sends you his heartiest"); + + print("congratulations and wishes you a prosperous life in your new home."); + throw new NoInputException(); + } + + private boolean riders1390(int j) throws NoInputException { + final double value = (Math.pow(m / 100 - 4, 2) + 72) / (Math.pow(m / 100 - 4, 2) + 12) - 1; + final double random = 10.0 * rnd(); + if (random > value) { + return false; + } + int gh = 0; + if (rnd() > .2) { + gh = 1; + } + print(); + print("Riders ahead! They " + (gh == 1 ? "don't " : "") + "look hostile."); + int gt; + do { + print("You can (1) run, (2) attack, (3) ignore them, or (4) circle wagons."); + gt = skb.inputInt(screen); + } while (gt < 0 || gt > 4); + if (rnd() < .2) { + gh = 1 - gh; + } + if (gh == 1) { + if (gt == 1) { + m = m + 15; + a = a - 5; + } else if (gt == 2) { + m = m - 5; + b = b - 100; + } else if (gt == 4) { + m = m - 20; + } + print("Riders were friendly, but check for possible losses."); + return true; + } + if (gt == 1) { + m = m + 20; + r = r - 7; + b = b - 150; + a = a - 20; + } else if (gt == 2) { + final int br = shoot3870(); + b = b - br * 40 - 80; + riderShoot(br); + } else if (gt == 3) { + if (rnd() > .8) { + print("They did not attack. Whew!"); + return true; + } + b = b - 150; + r = r - 7; + } else { + assert gt == 4; + final int br = shoot3870(); + b = b - br * 30 - 80; + m = m - 25; + riderShoot(br); + } + print("Riders were hostile. Better check for losses!"); + if (b >= 0) { + return true; + } + print(); + print("Oh, my gosh!"); + print("They're coming back and you're out of ammo! Your dreams turn to"); + print("dust as you and your family are massacred on the prairie."); + print3110(j); + return true; + + } + + private void riderShoot(final int br) { + if (br <= 1) { + print("Nice shooting - you drove them off."); + } else if (br <= 4) { + print("Kind of slow with your Colt .45."); + } else { + print("Pretty slow on the draw, partner. You got a nasty flesh wound."); + kh = 1; + print("You'll have to see the doc soon as you can."); + } + } + + private void montains2640(int j) throws NoInputException { + if (m <= 975) { + return; + } + final double mm = m / 100.0 - 15; + if (10 * rnd() > 9 - (mm * mm + 72) / (mm * mm + 12)) { + southPass2750(j); + return; + } + print("You're in rugged mountain country."); + if (rnd() <= .1) { + print("You get lost and lose valuable time trying to find the trail."); + m = m - 60; + southPass2750(j); + return; + } + if (rnd() > .11) { + print("The going is really slow; oxen are very tired."); + m = m - 45 - 50 * rnd(); + } else { + print("Trail cave in damages your wagon. You lose time and supplies."); + m = m - 20 - 30 * rnd(); + b = b - 200; + r = r - 3; + } + southPass2750(j); + + } + + private void southPass2750(int j) throws NoInputException { + if (kp == 1) { + + } + kp = 1; + if (rnd() < .8) { + + } + print("You made it safely through the South Pass....no snow!"); + km = 1; + if (rnd()<.7) { + print("Blizzard in the mountain pass. Going is slow; supplies are lost."); + kb = 1; + m = m - 30 - 40 * rnd(); + f = f - 12; + b = b - 200; + r = r - 5; + if (c>=18+2*rnd()) { + return; + } + dealWithIllness2880(j); + } + + } + + + + private void dealWithIllness2880(int j) throws NoInputException { + if (100 * rnd() < 10 + 35 * (e - 1)) { + print("Mild illness. Your own medicine will cure it."); + m -= 5; + r -= 1; + } else if (100 * rnd() < 100.0 - 40.0 / Math.pow(4.0, e - 1)) { + print("The whole family is sick. Your medicine will probably work okay."); + m -= 5; + r -= 2.5; + } else { + print("Serious illness in the family. You'll have to stop and see a doctor"); + print("soon. For now, your medicine will work."); + r -= 5; + ks = 1; + } + if (r <= 0) { + print("...if only you had enough."); + outOfMedicalSupplies3020(j); + } + + } + + private void eating1310(int j) throws NoInputException { + if (f < 5) { + die3000(j); + return; + } + do { + print("Do you want to eat (1) poorly, (2) moderately or (3) well ?"); + e = skb.inputInt(screen); + if (e < 1 || e > 3) { + print("Enter 1, 2, or 3, please."); + break; + } + final int ee = (int) (4 + 2.5 * e); + if (e == 1 && ee > f) { + f = 0; + return; + } + if (ee > f) { + print("You don't have enough to eat that well."); + break; + } + f -= ee; + return; + } while (true); + + } + + private void needDoctorBadly3010(int j) throws NoInputException { + print("You need a doctor badly but can't afford one."); + die3030(j); + } + + private void outOfMedicalSupplies3020(int j) throws NoInputException { + print("You have run out of all medical supplies."); + print(); + die3030(j); + } + + private void die3000(int j) throws NoInputException { + screen.clear(); + print("You run out of food and starve to death."); + print(); + print3110(j); + } + + private void die3030(int j) throws NoInputException { + print("The wilderness is unforgiving and you die of " + (kh == 1 ? "your injuries" : "pneumonia")); + die3060(j); + } + + private void die3060(int j) throws NoInputException { + print("Your family tries to push on, but finds the going too rough"); + print(" without you."); + print3110(j); + } + + private void print3110(int j) throws NoInputException { + print("Some travelers find the bodies of you and your"); + print("family the following spring. They give you a decent"); + print("burial and notify your next of kin."); + print(); + print("At the time of your unfortunate demise, you had been on the trail"); + final int d = 14 * j; + final int dm = (int) (d / 30.5); + final int dd = (int) (d - 30.5 * dm); + print("for " + dm + " months and " + dd + " days and had covered " + (int) ((m + 70)) + " miles."); + print(); + print("You had a few supplies left :"); + printInventory3350(); + throw new NoInputException(); + } + + private void question1000(int j) throws NoInputException { + int x; + if (j % 2 == 1) { + do { + print("Want to (1) stop at the next fort, (2) hunt, or (3) push on ?"); + x = skb.inputInt(screen); + if (x == 3) { + return; + } + if (x == 1) { + stopAtFort1100(j); + return; + } + if (x == 2) { + hunt1200(j); + if (kq == 0) { + return; + } + } + } while (true); + } else { + do { + print("Would you like to (1) hunt or (2) continue on ?"); + x = skb.inputInt(screen); + if (x == 2) { + return; + } + } while (x < 1 || x > 2); + if (x == 1) { + hunt1200(j); + } + } + + } + + private void hunt1200(int j) throws NoInputException { + kq = 0; + if (b <= 39) { + print("Tough luck. You don't have enough ammo to hunt."); + kq = 1; + return; + } + m = m - 45; + final int br = shoot3870(); + if (br <= 1) { + print("Right between the eyes... you got a big one!"); + print("Full bellies tonight!"); + b = b - 10 - 4 * rnd(); + f = f + 26 + 3 * rnd(); + return; + } + if (100.0 * rnd() < 13 * br) { + print("You missed completely... and your dinner got away."); + return; + } + print("Nice shot... right on target... good eatin' tonight!"); + f = f + 24 - 2 * br; + b = b - 10 - 3 * br; + return; + } + + private void stopAtFort1100(int j) throws NoInputException { + if (t <= 0) { + print("You sing with the folks there and get a good"); + print("night's sleep, but you have no money to buy anything."); + return; + } + + while (true) { + print("What would you like to spend on each of the following"); + print("Food?"); + final double p1 = skb.inputInt(screen); + print("Ammunition?"); + final double p2 = skb.inputInt(screen); + print("Clothing?"); + final double p3 = skb.inputInt(screen); + print("Medicine and supplies?"); + final double p4 = skb.inputInt(screen); + final double p = p1 + p2 + p3 + p4; + print("The storekeeper tallies up your bill. It comes to $" + ((int) p)); + if (t >= p) { + t = t - p; + f = f + .67 * p1; + b = b + 33 * p2; + c = c + .67 * p3; + r = r + .67 * p4; + return; + } + print("Uh, oh. That's more than you have. Better start over."); + } + } + + private void printInventory3350() { + // print("+------+------+------+---------+--------------------+"); + print(); + print("| Cash | Food | Ammo | Clothes | Medicine/parts/... |"); + print("+------+------+------+---------+--------------------+"); + if (f < 0) { + f = 0; + } + if (b < 0) { + b = 0; + } + if (c < 0) { + c = 0; + } + if (r < 0) { + r = 0; + } + print(String.format("|%5d |%5d |%5d | %5d | %5d |", (int) t, (int) f, (int) b, (int) c, (int) r)); + print("+------+------+------+---------+--------------------+"); + print(); + } + + private String whereAreWe() { + if (m < 5) { + return "on the high prairie."; + } + if (m < 200) { + return "near Independence Crossing on the Big Blue River."; + } + if (m < 350) { + return "following the Platte River."; + } + if (m < 450) { + return "near Fort Kearney."; + } + if (m < 600) { + return "following the North Platte River."; + } + if (m < 750) { + return "within sight of Chimney Rock."; + } + if (m < 850) { + return "near Fort Laramie."; + } + if (m < 1000) { + return "close upon Independence Rock."; + } + if (m < 1050) { + return "in the Big Horn Mountains."; + } + if (m < 1150) { + return "following the Green River."; + } + if (m < 1250) { + return "not too far from Fort Hall."; + } + if (m < 1400) { + return "following the Snake River."; + } + if (m < 1550) { + return "not far from Fort Boise."; + } + if (m < 1850) { + return "in the Blue Mountains."; + } + return "following the Columbia River"; + + } + + private void printInitialScenario490() { + print(" Your journey over the Oregon Trail takes place in 1847."); + print(); + print("Starting in Independence, Missouri, you plan to take your family of"); + print("five over 2040 tough miles to Oregon City."); + print(); + print(" Having saved $420 for the trip, you bought a wagon for $70 and"); + print("now have to purchase the following items :"); + print(); + print(" * Oxen (spending more will buy you a larger and better team which"); + print(" will be faster so you'll be on the trail for less time)"); + print(" * Food (you'll need ample food to keep up your strength and health)"); + print(" * Ammunition ($1 buys a belt of 50 bullets. You'll need ammo for"); + print(" hunting and for fighting off attacks by bandits and animals)"); + print(" * Clothing (you'll need warm clothes, especially when you hit the"); + print(" snow and freezing weather in the mountains)"); + print(" * Other supplies (includes medicine, first-aid supplies, tools, and"); + print(" wagon parts for unexpected emergencies)"); + print(); + print(" You can spend all your money at the start or save some to spend"); + print("at forts along the way. However, items cost more at the forts. You"); + print("can also hunt for food if you run low."); + print(); + + } + + private void initialPurchasesOfPlayer690() throws NoInputException { + if (skb.hasMore()) { + screen.clear(); + } + do { + print("How much do you want to pay for a team of oxen ?"); + a = skb.inputInt(screen); + if (a < 100) { + print("No one in town has a team that cheap"); + continue; + } + break; + } while (true); + if (a >= 151) { + print("You choose an honest dealer who tells you that $" + a + " is too much for"); + print("a team of oxen. He charges you $150 and gives you $" + (a - 150) + " change."); + a = 150; + } + do { + print(); + print("How much do you want to spend on food ?"); + f = skb.inputInt(screen); + if (f <= 13) { + print("That won't even get you to the Kansas River"); + print(" - better spend a bit more."); + continue; + } + if (a + f > 300) { + print("You wont't have any for ammo and clothes."); + continue; + } + break; + } while (true); + do { + print(); + print("How much do you want to spend on ammunition ?"); + b = skb.inputInt(screen); + if (b < 2) { + print("Better take a bit just for protection."); + continue; + } + if (a + f + b > 320) { + print("That won't leave any money for clothes."); + continue; + } + break; + } while (true); + do { + print(); + print("How much do you want to spend on clothes ?"); + c = skb.inputInt(screen); + if (c <= 24) { + print("Your family is going to be mighty cold in."); + print("the montains."); + print("Better spend a bit more."); + continue; + } + if (a + f + b + c > 345) { + print("That leaves nothing for medecine."); + continue; + } + break; + } while (true); + do { + print(); + screen.print("How much for medecine, bandage, repair parts, etc. ?"); + r = skb.inputInt(screen); + if (r <= 5) { + print("That's not at all wise."); + continue; + } + if (a + f + b + c + r > 350) { + print("You don't have that much money."); + continue; + } + break; + } while (true); + t = 350 - a - f - b - c - r; + print(); + print("You now have $" + ((int) t) + " left."); + b = 50 * b; + } + + private void initialShootingRanking920() throws NoInputException { + print(); + print("Please rank your shooting (typing) ability as follows :"); + print(" (1) Ace marksman (2) Good shot (3) Fair to middlin'"); + print(" (4) Need more practice (5) Shaky knees"); + do { + print(); + print("How do you rank yourself ?"); + dr = skb.inputInt(screen); + if (dr >= 1 && dr <= 6) { + return; + } + print("Please enter 1, 2, 3, 4 or 5."); + } while (true); + } + + private int e; + private int a; + private double b; + private double f; + private double c; + private double r; + private double t; + private int dr; + private double m; + + private int getTime() { + return (int) ((System.currentTimeMillis() / 1000L) % 83); + } + + private String getRandomShootingWord() { + int rn = (int) (rnd() * 4); + switch (rn) { + case 0: + return "pow"; + case 1: + return "bang"; + case 2: + return "blam"; + } + return "whop"; + } + + private int shoot3870() throws NoInputException { + final String word1 = getRandomShootingWord() + getTime(); + print("Type: " + word1); + final String typed1 = skb.input(screen); + final int time = getDeltaTime(typed1); + final String word2 = getRandomShootingWord() + time; + print("Type: " + word2); + final String typed2 = skb.input(screen); + int duration = extractInt(typed2) - dr - 1; + // 3870 'Subroutine to shoot gun + // 3880 RN = 1 + INT(4 * RND(1)) : 'Pick a random shooting word + // 3890 S1 = 60 * VAL(MID$(TIME$, 4, 2)) + VAL(RIGHT$(TIME$, 2)) : + // 'Start timer + // 3900 PRINT "Type " S$(RN); : INPUT X$ + // 3910 IF S$(RN)< >X$ AND S$(RN + 4)< >X$ THEN PRINT "Nope. Try again. + // "; : GOTO 3900 + // 3920 S2 = 60 * VAL(MID$(TIME$, 4, 2)) + VAL(RIGHT$(TIME$, 2)) : 'End + // timer + // 3930 BR = S2 - S1 - DR - 1 : RETURN + if (duration < 0) { + return 0; + } + return duration; + } + + private int extractInt(String typed) { + final String s = typed.replaceAll("\\D", ""); + if (s.length() == 0) { + return 0; + } + return Integer.parseInt(s); + } + + private int getDeltaTime(String typed) { + final int was = extractInt(typed); + int diff = getTime() - was; + if (diff < 0) { + diff += 83; + } + return diff; + } +} diff --git a/src/net/sourceforge/plantuml/oregon/PSystemOregon.java b/src/net/sourceforge/plantuml/oregon/PSystemOregon.java new file mode 100644 index 000000000..603f154fd --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/PSystemOregon.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4041 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.awt.Color; +import java.awt.Font; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.graphic.GraphicStrings; + +public class PSystemOregon extends AbstractPSystem { + + private Screen screen; + + public PSystemOregon(Keyboard keyboard) { + final BasicGame game = new OregonBasicGame(); + try { + game.run(keyboard); + this.screen = game.getScreen(); +// this.screen = new Screen(); +// screen.print("Game ended??"); + } catch (NoInputException e) { + this.screen = game.getScreen(); + } + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + getGraphicStrings().writeImage(os, fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getGraphicStrings().writeImage(os, fileFormat); + } + + private GraphicStrings getGraphicStrings() throws IOException { + final Font font = new Font("Monospaced", Font.PLAIN, 14); + return new GraphicStrings(screen.getLines(), font, Color.GREEN, Color.BLACK, true); + } + + public String getDescription() { + return "(The Oregon Trail)"; + } + +} diff --git a/src/net/sourceforge/plantuml/oregon/PSystemOregonFactory.java b/src/net/sourceforge/plantuml/oregon/PSystemOregonFactory.java new file mode 100644 index 000000000..4ebb503b1 --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/PSystemOregonFactory.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemOregonFactory implements PSystemBasicFactory { + + private PSystemOregon system; + private List inputs; + + public PSystemOregonFactory() { + reset(); + } + + public void reset() { + inputs = null; + } + + public PSystemOregon getSystem() { + final Keyboard keyboard; + if (inputs == null) { + keyboard = new KeyboardList(""); + } else { + keyboard = new KeyboardList(inputs); + } + system = new PSystemOregon(keyboard); + return system; + } + + public boolean executeLine(String line) { + if (inputs == null && line.equalsIgnoreCase("run oregon trail")) { + inputs = new ArrayList(); + return true; + } + if (inputs == null) { + return false; + } + inputs.add(line); + return true; + } +} diff --git a/src/net/sourceforge/plantuml/oregon/Screen.java b/src/net/sourceforge/plantuml/oregon/Screen.java new file mode 100644 index 000000000..954ab945c --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/Screen.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Screen { + private final List lines = new ArrayList(); + + public void clear() { + lines.clear(); + } + + public void print(String s) { + lines.add(s); + } + + public void print() { + lines.add(" "); + } + + public List getLines() { + return Collections.unmodifiableList(lines); + } + + public String getLastLine() { + return lines.get(lines.size()-1); + } + +} diff --git a/src/net/sourceforge/plantuml/oregon/SecureCoder.java b/src/net/sourceforge/plantuml/oregon/SecureCoder.java new file mode 100644 index 000000000..848fcd0c1 --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/SecureCoder.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +public class SecureCoder { + + private static final int m[] = { 38, 152, 264, 491, 573, 616, 727, 880, 905, 1090, 1188, 1315, 1544, 1603, 1756, + 1831, 1962, 2025, 2100, 2257, 2381, 2469, 2536, 2714, 2948, 3077, 3166, 3219, 3340, 3455, 3701, 3892, 3934, + 4193, 4372, 4404, 4521, 4650, 4739, 4865, 4987, 5053, 5135, 5282, 5309, 5446, 5628, 5817, 5970, 6002, 6174, + 6295, 6367, 6420, 6558, 6689, 6913, 7061, 7129, 7206, 7333, 7510, 7697, 7742, 7854, 8084, 8147, 8230, 8326, + 8412, 8599, 8675, 8763, 8808, 8951, 9049, 9111, 9223, 9394, 9478, 9507, 9632, 9785 }; + + private static final int dec[] = new int[10000]; + + static { + for (int i = 0; i < dec.length; i++) { + dec[i] = -1; + } + for (int i = 0; i < m.length; i++) { + final int enc = m[i]; + dec[enc] = i; + for (int n : MagicTable.getNeighboors(enc)) { + if (dec[n] != -1) { + throw new IllegalStateException(); + } + dec[n] = i + 1000; + } + } + } + + public int encode(int i) { + return m[i]; + } + + public int decode(int v) { + return dec[v]; + } + +} diff --git a/src/net/sourceforge/plantuml/oregon/SmartKeyboard.java b/src/net/sourceforge/plantuml/oregon/SmartKeyboard.java new file mode 100644 index 000000000..a847a6478 --- /dev/null +++ b/src/net/sourceforge/plantuml/oregon/SmartKeyboard.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4639 $ + * + */ +package net.sourceforge.plantuml.oregon; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class SmartKeyboard { + + private final Keyboard keyboard; + private final List history = new ArrayList(); + + public SmartKeyboard(Keyboard keyboard) { + this.keyboard = keyboard; + } + + public String input(Screen screen) throws NoInputException { + final String s = keyboard.input(); + history.add(s); + screen.print("? " + s); + return s; + } + + public int inputInt(Screen screen) throws NoInputException { + final String s = input(screen); + if (s.matches("\\d+") == false) { + screen.print("Please enter a valid number instead of " + s); + throw new NoInputException(); + } + return Integer.parseInt(s); + } + + public boolean hasMore() { + return keyboard.hasMore(); + } + + public List getHistory() { + return Collections.unmodifiableList(history); + } + +} diff --git a/src/net/sourceforge/plantuml/png/Metadata.java b/src/net/sourceforge/plantuml/png/Metadata.java new file mode 100644 index 000000000..3dd22d8a6 --- /dev/null +++ b/src/net/sourceforge/plantuml/png/Metadata.java @@ -0,0 +1,125 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +public class Metadata { + + public static void main(String[] args) throws IOException { + final Metadata meta = new Metadata(); + final int length = args.length; + for (int i = 0; i < length; i++) { + meta.readAndDisplayMetadata(new File(args[i])); + } + } + + public void readAndDisplayMetadata(File file) throws IOException { + final ImageInputStream iis = ImageIO.createImageInputStream(file); + final Iterator readers = ImageIO.getImageReaders(iis); + + if (readers.hasNext()) { + // pick the first available ImageReader + final ImageReader reader = readers.next(); + + // attach source to the reader + reader.setInput(iis, true); + + // read metadata of first image + final IIOMetadata metadata = reader.getImageMetadata(0); + + final String[] names = metadata.getMetadataFormatNames(); + final int length = names.length; + for (int i = 0; i < length; i++) { + displayMetadata(metadata.getAsTree(names[i])); + } + } + } + + private void displayMetadata(Node root) { + displayMetadata(root, 0); + } + + private void indent(int level) { + for (int i = 0; i < level; i++) { + System.out.print(" "); + } + } + + private void displayMetadata(Node node, int level) { + // print open tag of element + indent(level); + System.out.print("<" + node.getNodeName()); + final NamedNodeMap map = node.getAttributes(); + if (map != null) { + + // print attribute values + final int length = map.getLength(); + for (int i = 0; i < length; i++) { + final Node attr = map.item(i); + System.out.print(" " + attr.getNodeName() + "=\"" + attr.getNodeValue() + "\""); + } + } + + Node child = node.getFirstChild(); + if (child == null) { + // no children, so close element and return + System.out.println("/>"); + return; + } + + // children, so close current tag + System.out.println(">"); + while (child != null) { + // print children recursively + displayMetadata(child, level + 1); + child = child.getNextSibling(); + } + + // print close tag of element + indent(level); + System.out.println(""); + } + +} diff --git a/src/net/sourceforge/plantuml/png/MetadataTag.java b/src/net/sourceforge/plantuml/png/MetadataTag.java new file mode 100644 index 000000000..c0923b9ac --- /dev/null +++ b/src/net/sourceforge/plantuml/png/MetadataTag.java @@ -0,0 +1,117 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +public class MetadataTag { + + private final File f; + private final String tag; + + public MetadataTag(File f, String tag) { + this.f = f; + this.tag = tag; + } + + public String getData() throws IOException { + final ImageInputStream iis = ImageIO.createImageInputStream(f); + final Iterator readers = ImageIO.getImageReaders(iis); + + if (readers.hasNext()) { + // pick the first available ImageReader + final ImageReader reader = readers.next(); + + // attach source to the reader + reader.setInput(iis, true); + + // read metadata of first image + final IIOMetadata metadata = reader.getImageMetadata(0); + + final String[] names = metadata.getMetadataFormatNames(); + final int length = names.length; + for (int i = 0; i < length; i++) { + final String result = displayMetadata(metadata.getAsTree(names[i])); + if (result != null) { + return result; + } + } + } + + return null; + } + + private String displayMetadata(Node root) { + return displayMetadata(root, 0); + } + + private String displayMetadata(Node node, int level) { + final NamedNodeMap map = node.getAttributes(); + if (map != null) { + final Node keyword = map.getNamedItem("keyword"); + if (keyword != null && tag.equals(keyword.getNodeValue())) { + final Node text = map.getNamedItem("value"); + if (text != null) { + return text.getNodeValue(); + } + } + } + + Node child = node.getFirstChild(); + + // children, so close current tag + while (child != null) { + // print children recursively + final String result = displayMetadata(child, level + 1); + if (result != null) { + return result; + } + child = child.getNextSibling(); + } + + return null; + + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngIO.java b/src/net/sourceforge/plantuml/png/PngIO.java new file mode 100644 index 000000000..570ec2e94 --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngIO.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4301 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.Log; + +public class PngIO { + + private static final String copyleft = "Generated by http://plantuml.sourceforge.net"; + + public static void write(RenderedImage image, File file) throws IOException { + write(image, file, null); + } + + public static void write(RenderedImage image, OutputStream os) throws IOException { + write(image, os, null); + } + + public static void write(RenderedImage image, File file, String metadata) throws IOException { + OutputStream os = null; + try { + os = new FileOutputStream(file); + write(image, os, metadata); + } finally { + if (os != null) { + os.close(); + } + } + Log.debug("File is " + file); + Log.debug("File size " + file.length()); + if (file.length() == 0) { + Log.error("File size is zero: " + file); + ImageIO.write(image, "png", file); + } + } + + public static void write(RenderedImage image, OutputStream os, String metadata) throws IOException { + if (checkPNGMetadata()) { + PngIOMetadata.writeWithMetadata(image, os, metadata); + } else { + ImageIO.write(image, "png", os); + } + + } + + static boolean checkPNGMetadata() { + try { + final Class cl = Class.forName("com.sun.imageio.plugins.png.PNGMetadata"); + if (cl == null) { + Log.info("Cannot load com.sun.imageio.plugins.png.PNGMetadata"); + return false; + } + Log.info("Ok for com.sun.imageio.plugins.png.PNGMetadata"); + return true; + } catch (Exception e) { + Log.info("Error loading com.sun.imageio.plugins.png.PNGMetadata " + e); + return false; + } + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngIOMetadata.java b/src/net/sourceforge/plantuml/png/PngIOMetadata.java new file mode 100644 index 000000000..262f1d634 --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngIOMetadata.java @@ -0,0 +1,104 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4231 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.image.RenderedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriter; + +import net.sourceforge.plantuml.Log; + +import com.sun.imageio.plugins.png.PNGMetadata; + +public class PngIOMetadata { + + private static final String copyleft = "Generated by http://plantuml.sourceforge.net"; + + public static void writeWithMetadata(RenderedImage image, OutputStream os, String metadata) throws IOException { + + final ImageWriter imagewriter = getImageWriter(); + Log.debug("PngIOMetadata imagewriter=" + imagewriter); + + imagewriter.setOutput(ImageIO.createImageOutputStream(os)); + + // Create & populate metadata + final PNGMetadata pngMetadata = new PNGMetadata(); + + if (metadata != null) { + pngMetadata.zTXt_keyword.add("plantuml"); + pngMetadata.zTXt_compressionMethod.add(new Integer(0)); + pngMetadata.zTXt_text.add(metadata); + // System.err.println("metadata=" + metadata); + // if (metadata.equals("Generated by + // http://plantuml.sourceforge.net")) { + // throw new IllegalArgumentException(); + // } + } + + pngMetadata.tEXt_keyword.add("copyleft"); + pngMetadata.tEXt_text.add(copyleft); + + Log.debug("PngIOMetadata pngMetadata=" + pngMetadata); + + // Render the PNG to file + final IIOImage iioImage = new IIOImage(image, null, pngMetadata); + Log.debug("PngIOMetadata iioImage=" + iioImage); + // Attach the metadata + imagewriter.write(null, iioImage, null); + Log.debug("PngIOMetadata before flush"); + os.flush(); + Log.debug("PngIOMetadata after flush"); + } + + private static ImageWriter getImageWriter() { + final Iterator iterator = ImageIO.getImageWritersBySuffix("png"); + for (final Iterator it = ImageIO.getImageWritersBySuffix("png"); it.hasNext();) { + final ImageWriter imagewriter = iterator.next(); + Log.debug("PngIOMetadata countImageWriter = " + it.next()); + if (imagewriter.getClass().getName().equals("com.sun.imageio.plugins.png.PNGImageWriter")) { + Log.debug("PngIOMetadata Found sun PNGImageWriter"); + return imagewriter; + } + + } + Log.debug("Using first one"); + return ImageIO.getImageWritersBySuffix("png").next(); + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngRotation.java b/src/net/sourceforge/plantuml/png/PngRotation.java new file mode 100644 index 000000000..bcb07f8cc --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngRotation.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; + +import net.sourceforge.plantuml.Log; + +public class PngRotation { + + public static BufferedImage process(BufferedImage im) { + + Log.info("Rotation"); + + final BufferedImage newIm = new BufferedImage(im.getHeight(), im.getWidth(), BufferedImage.TYPE_INT_RGB); + final Graphics2D g2d = newIm.createGraphics(); + + final AffineTransform at = new AffineTransform(0, 1, 1, 0, 0, 0); + at.concatenate(new AffineTransform(-1, 0, 0, 1, im.getWidth(), 0)); + g2d.setTransform(at); + + g2d.drawImage(im, 0, 0, null); + g2d.dispose(); + + return newIm; + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngScaler.java b/src/net/sourceforge/plantuml/png/PngScaler.java new file mode 100644 index 000000000..9f4016af4 --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngScaler.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4179 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +public class PngScaler { + + public static BufferedImage scale(BufferedImage im, double scale) { + if (scale == 1 || scale == 0) { + return im; + } + + final int width = (int) (im.getWidth() * scale); + final int height = (int) (im.getHeight() * scale); + + final BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + final Graphics2D g = resizedImage.createGraphics(); + g.setComposite(AlphaComposite.Src); + + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g.drawImage(im, 0, 0, width, height, null); + g.dispose(); + return resizedImage; + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngSegment.java b/src/net/sourceforge/plantuml/png/PngSegment.java new file mode 100644 index 000000000..31951e31b --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngSegment.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.png; + +class PngSegment { + + private final int totalSize; + private final int nbPiece; + + public PngSegment(int totalSize, int nbPiece) { + this.nbPiece = nbPiece; + this.totalSize = totalSize; + } + + public int getStart(int idx) { + if (idx < 0 || idx > nbPiece - 1) { + throw new IllegalArgumentException(); + } + return (int) (1.0 * totalSize / nbPiece * idx); + } + + public int getLen(int idx) { + if (idx < 0 || idx > nbPiece - 1) { + throw new IllegalArgumentException(); + } + return (int) (1.0 * totalSize / nbPiece); + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngSizer.java b/src/net/sourceforge/plantuml/png/PngSizer.java new file mode 100644 index 000000000..b2418064b --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngSizer.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4984 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +import net.sourceforge.plantuml.Log; + +public class PngSizer { + + static public BufferedImage process(BufferedImage im, int minsize) { + + if (minsize != Integer.MAX_VALUE) { + return resize(im, minsize); + } + return im; + + } + + static private BufferedImage resize(BufferedImage im, int minsize) { + Log.info("Resizing file to " + minsize); + + if (im.getWidth() >= minsize) { + return im; + } + + final BufferedImage newIm = new BufferedImage(minsize, im.getHeight(), BufferedImage.TYPE_INT_RGB); + final Graphics2D g2d = newIm.createGraphics(); + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, newIm.getWidth(), newIm.getHeight()); + final int delta = (minsize - im.getWidth()) / 2; + g2d.drawImage(im, delta, 0, null); + + g2d.dispose(); + + return newIm; + + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngSplitter.java b/src/net/sourceforge/plantuml/png/PngSplitter.java new file mode 100644 index 000000000..f735945ff --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngSplitter.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4165 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.sequencediagram.graphic.SequenceDiagramFileMaker; + +public class PngSplitter { + + private final List files = new ArrayList(); + + public PngSplitter(File pngFile, int horizontalPages, int verticalPages, String source) throws IOException { + if (horizontalPages == 1 && verticalPages == 1) { + this.files.add(pngFile); + return; + } + + Log.info("Splitting " + horizontalPages + " x " + verticalPages); + final File full = new File(pngFile.getParentFile(), pngFile.getName() + ".tmp"); + Thread.yield(); + full.delete(); + Thread.yield(); + final boolean ok = pngFile.renameTo(full); + Thread.yield(); + if (ok == false) { + throw new IOException("Cannot rename"); + } + + Thread.yield(); + final BufferedImage im = ImageIO.read(full); + Thread.yield(); + final PngSegment horizontalSegment = new PngSegment(im.getWidth(), horizontalPages); + final PngSegment verticalSegment = new PngSegment(im.getHeight(), verticalPages); + + int x = 0; + for (int i = 0; i < horizontalPages; i++) { + for (int j = 0; j < verticalPages; j++) { + final File f = SequenceDiagramFileMaker.computeFilename(pngFile, x++, FileFormat.PNG); + this.files.add(f); + final BufferedImage imPiece = im.getSubimage(horizontalSegment.getStart(i), + verticalSegment.getStart(j), horizontalSegment.getLen(i), verticalSegment.getLen(j)); + Thread.yield(); + PngIO.write(imPiece, f, source); + Thread.yield(); + } + } + + full.delete(); + Log.info("End of splitting"); + } + + public List getFiles() { + return Collections.unmodifiableList(files); + } + +} diff --git a/src/net/sourceforge/plantuml/png/PngTitler.java b/src/net/sourceforge/plantuml/png/PngTitler.java new file mode 100644 index 000000000..7a6adc32e --- /dev/null +++ b/src/net/sourceforge/plantuml/png/PngTitler.java @@ -0,0 +1,150 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4179 $ + * + */ +package net.sourceforge.plantuml.png; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.Dimension2D; +import java.awt.image.BufferedImage; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.VerticalPosition; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; + +public class PngTitler { + + private final Color textColor; + private final List text; + private final int fontSize; + private final String fontFamily; + private final HorizontalAlignement horizontalAlignement; + private final VerticalPosition verticalPosition; + + public PngTitler(Color textColor, List text, int fontSize, String fontFamily, + HorizontalAlignement horizontalAlignement, VerticalPosition verticalPosition) { + this.textColor = textColor; + this.text = text; + this.fontSize = fontSize; + this.fontFamily = fontFamily; + this.horizontalAlignement = horizontalAlignement; + this.verticalPosition = verticalPosition; + + } + + public BufferedImage processImage(BufferedImage im, Color background, int margin) { + if (text != null && text.size() > 0) { + im = addTitle(im, background, textColor, text, fontSize, fontFamily, horizontalAlignement, + verticalPosition, margin); + } + return im; + + } + + public Dimension2D getTextDimension(StringBounder stringBounder) { + final TextBlock textBloc = getTextBlock(); + if (textBloc == null) { + return null; + } + return textBloc.calculateDimension(stringBounder); + } + + public TextBlock getTextBlock() { + if (text == null || text.size() == 0) { + return null; + } + final Font normalFont = new Font(fontFamily, Font.PLAIN, fontSize); + return TextBlockUtils.create(text, normalFont, textColor, horizontalAlignement); + } + + static private BufferedImage addTitle(BufferedImage im, Color background, Color textColor, List text, + int fontSize, String fontFamily, HorizontalAlignement horizontalAlignement, + VerticalPosition verticalPosition, int margin) { + + final Font normalFont = new Font(fontFamily, Font.PLAIN, fontSize); + final Graphics2D oldg2d = im.createGraphics(); + final TextBlock textBloc = TextBlockUtils.create(text, normalFont, textColor, horizontalAlignement); + final Dimension2D dimText = textBloc.calculateDimension(StringBounderUtils.asStringBounder(oldg2d)); + oldg2d.dispose(); + + final double width = Math.max(im.getWidth(), dimText.getWidth()); + final double height = im.getHeight() + dimText.getHeight() + margin; + + final BufferedImage newIm = new BufferedImage((int) width, (int) height, BufferedImage.TYPE_INT_RGB); + final Graphics2D g2d = newIm.createGraphics(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + g2d.setColor(background); + g2d.fillRect(0, 0, newIm.getWidth(), newIm.getHeight()); + final double xText; + if (horizontalAlignement == HorizontalAlignement.LEFT) { + xText = 2; + } else if (horizontalAlignement == HorizontalAlignement.RIGHT) { + xText = width - dimText.getWidth() - 2; + } else if (horizontalAlignement == HorizontalAlignement.CENTER) { + xText = (width - dimText.getWidth()) / 2; + } else { + xText = 0; + assert false; + } + + final int yText; + final int yImage; + + if (verticalPosition == VerticalPosition.TOP) { + yText = 0; + yImage = (int) dimText.getHeight() + margin; + } else { + yText = im.getHeight() + margin; + yImage = 0; + } + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + textBloc.drawU(new UGraphicG2d(g2d, null), xText, yText); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + final double delta2 = (width - im.getWidth()) / 2; + + g2d.drawImage(im, (int) delta2, yImage, null); + g2d.dispose(); + return newIm; + + } +} diff --git a/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java b/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java new file mode 100644 index 000000000..f883850ef --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java @@ -0,0 +1,106 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3831 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.graphic.StringBounder; + +abstract class AbstractEntityImage2 implements IEntityImageBlock { + + private final IEntity entity; + + final private Color red = new Color(Integer.parseInt("A80036", 16)); + final private Color yellow = new Color(Integer.parseInt("FEFECE", 16)); + private final Color yellowNote = new Color(Integer.parseInt("FBFB77", 16)); + + final private Font font14 = new Font("SansSerif", Font.PLAIN, 14); + final private Font font17 = new Font("Courier", Font.BOLD, 17); + final private Color green = new Color(Integer.parseInt("ADD1B2", 16)); + final private Color violet = new Color(Integer.parseInt("B4A7E5", 16)); + final private Color blue = new Color(Integer.parseInt("A9DCDF", 16)); + final private Color rose = new Color(Integer.parseInt("EB937F", 16)); + + public AbstractEntityImage2(IEntity entity) { + if (entity == null) { + throw new IllegalArgumentException("entity null"); + } + this.entity = entity; + } + + public abstract Dimension2D getDimension(StringBounder stringBounder); + + protected final IEntity getEntity() { + return entity; + } + + protected final Color getRed() { + return red; + } + + protected final Color getYellow() { + return yellow; + } + + protected final Font getFont17() { + return font17; + } + + protected final Font getFont14() { + return font14; + } + + protected final Color getGreen() { + return green; + } + + protected final Color getViolet() { + return violet; + } + + protected final Color getBlue() { + return blue; + } + + protected final Color getRose() { + return rose; + } + + protected final Color getYellowNote() { + return yellowNote; + } +} diff --git a/src/net/sourceforge/plantuml/posimo/BezierUtils.java b/src/net/sourceforge/plantuml/posimo/BezierUtils.java new file mode 100644 index 000000000..405ca73d9 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/BezierUtils.java @@ -0,0 +1,169 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Shape; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; + +public class BezierUtils { + + static double getEndingAngle(final CubicCurve2D.Double left) { + if (left.getCtrlP2().equals(left.getP2())) { + // assert left.getP1().equals(left.getCtrlP1()); + return getAngle(left.getP1(), left.getP2()); + } + return getAngle(left.getCtrlP2(), left.getP2()); + } + + static double getStartingAngle(final CubicCurve2D.Double left) { + if (left.getP1().equals(left.getCtrlP1())) { + // assert left.getCtrlP2().equals(left.getP2()); + return getAngle(left.getP1(), left.getP2()); + } + return getAngle(left.getP1(), left.getCtrlP1()); + } + + static double getAngle(Point2D p1, Point2D p2) { + if (p1.equals(p2)) { + throw new IllegalArgumentException(); + } + double a = -Math.atan2(p2.getY() - p1.getY(), p2.getX() - p1.getX()); + a = a * 180.0 / Math.PI; + a -= 90; + if (a >= 360.0) { + a -= 360.0; + } + if (a < 0.0) { + a += 360.0; + } + return a; + } + + static boolean isCutting(CubicCurve2D.Double bez, Shape shape) { + final boolean contains1 = shape.contains(bez.x1, bez.y1); + final boolean contains2 = shape.contains(bez.x2, bez.y2); + return contains1 ^ contains2; + } + + static void shorten(CubicCurve2D.Double bez, Shape shape) { + final boolean contains1 = shape.contains(bez.x1, bez.y1); + final boolean contains2 = shape.contains(bez.x2, bez.y2); + if (contains1 ^ contains2 == false) { + throw new IllegalArgumentException(); + } + if (contains1 == false) { + bez.setCurve(bez.x2, bez.y2, bez.ctrlx2, bez.ctrly2, bez.ctrlx1, bez.ctrly1, bez.x1, bez.y1); + } + assert shape.contains(bez.x1, bez.y1) && shape.contains(bez.x2, bez.y2) == false; + final CubicCurve2D.Double left = new CubicCurve2D.Double(); + final CubicCurve2D.Double right = new CubicCurve2D.Double(); + subdivide(bez, left, right, 0.5); + + if (isCutting(left, shape) ^ isCutting(right, shape) == false) { + throw new IllegalArgumentException(); + } + + if (isCutting(left, shape)) { + bez.setCurve(left); + } else { + bez.setCurve(right); + } + + } + + public static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right, final double coef) { + final double coef1 = coef; + final double coef2 = 1 - coef; + final double centerxA = src.getCtrlX1() * coef1 + src.getCtrlX2() * coef2; + final double centeryA = src.getCtrlY1() * coef1 + src.getCtrlY2() * coef2; + + final double ctrlx1 = src.getX1() * coef1 + src.getCtrlX1() * coef1; + final double ctrly1 = src.getY1() * coef1 + src.getCtrlY1() * coef1; + final double ctrlx2 = src.getX2() * coef1 + src.getCtrlX2() * coef1; + final double ctrly2 = src.getY2() * coef1 + src.getCtrlY2() * coef1; + + final double ctrlx12 = ctrlx1 * coef1 + centerxA * coef1; + final double ctrly12 = ctrly1 * coef1 + centeryA * coef1; + final double ctrlx21 = ctrlx2 * coef1 + centerxA * coef1; + final double ctrly21 = ctrly2 * coef1 + centeryA * coef1; + final double centerxB = ctrlx12 * coef1 + ctrlx21 * coef1; + final double centeryB = ctrly12 * coef1 + ctrly21 * coef1; + left.setCurve(src.getX1(), src.getY1(), ctrlx1, ctrly1, ctrlx12, ctrly12, centerxB, centeryB); + right.setCurve(centerxB, centeryB, ctrlx21, ctrly21, ctrlx2, ctrly2, src.getX2(), src.getY2()); + } + + static double dist(CubicCurve2D.Double seg) { + return Point2D.distance(seg.x1, seg.y1, seg.x2, seg.y2); + } + + static double dist(Line2D.Double seg) { + return Point2D.distance(seg.x1, seg.y1, seg.x2, seg.y2); + } + + static public Point2D middle(Line2D.Double seg) { + return new Point2D.Double((seg.x1 + seg.x2) / 2, (seg.y1 + seg.y2) / 2); + } + + static public Point2D middle(Point2D p1, Point2D p2) { + return new Point2D.Double((p1.getX() + p2.getX()) / 2, (p1.getY() + p2.getY()) / 2); + } + + public static Point2D intersect(Line2D.Double orig, Shape shape) { + final Line2D.Double copy = new Line2D.Double(orig.x1, orig.y1, orig.x2, orig.y2); + final boolean contains1 = shape.contains(copy.x1, copy.y1); + final boolean contains2 = shape.contains(copy.x2, copy.y2); + if (contains1 ^ contains2 == false) { + //return new Point2D.Double(orig.x2, orig.y2); + throw new IllegalArgumentException(); + } + while (true) { + final double mx = (copy.x1 + copy.x2) / 2; + final double my = (copy.y1 + copy.y2) / 2; + final boolean containsMiddle = shape.contains(mx, my); + if (contains1 == containsMiddle) { + copy.x1 = mx; + copy.y1 = my; + } else { + copy.x2 = mx; + copy.y2 = my; + } + if (dist(copy) < 1) { + return new Point2D.Double(mx, my); + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/Block.java b/src/net/sourceforge/plantuml/posimo/Block.java new file mode 100644 index 000000000..54e3ea8c0 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Block.java @@ -0,0 +1,98 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.Locale; + +import net.sourceforge.plantuml.Dimension2DDouble; + +public class Block implements Clusterable { + + private final int uid; + private final double width; + private final double height; + private double x; + private double y; + + public Block(int uid, double width, double height) { + this.uid = uid; + this.width = width; + this.height = height; + } + + @Override + public String toString() { + return "BLOCK " + uid; + } + + public String toStringPosition() { + return String.format(Locale.US, "x=%9.2f y=%9.2f w=%9.2f h=%9.2f", x, y, width, height); + } + + public int getUid() { + return uid; + } + + public Cluster getParent() { + // TODO Auto-generated method stub + return null; + } + + public Point2D getPosition() { + return new Point2D.Double(x, y); + } + + public Dimension2D getSize() { + return new Dimension2DDouble(width, height); + } + + public void setCenterX(double center) { + this.x = center - width / 2; + } + + public void setCenterY(double center) { + this.y = center - height / 2; + } + + public final void setX(double x) { + this.x = x; + } + + public final void setY(double y) { + this.y = y; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/Cluster.java b/src/net/sourceforge/plantuml/posimo/Cluster.java new file mode 100644 index 000000000..ff90c2837 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Cluster.java @@ -0,0 +1,138 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import net.sourceforge.plantuml.Dimension2DDouble; + +public class Cluster implements Clusterable { + + private static int CPT = 1; + + private final Cluster parent; + private final Collection blocs = new ArrayList(); + private final Collection children = new ArrayList(); + private final int uid = CPT++; + private double x; + private double y; + private double width; + private double height; + + public Cluster(Cluster parent) { + this.parent = parent; + if (parent != null) { + parent.children.add(this); + } + } + + public Collection getSubClusters() { + return Collections.unmodifiableCollection(children); + } + + public Collection getRecursiveContents() { + final Collection result = new ArrayList(); + addContentRecurse(result); + return Collections.unmodifiableCollection(result); + } + + private void addContentRecurse(Collection result) { + result.addAll(blocs); + for (Cluster c : children) { + c.addContentRecurse(result); + } + + } + + public int getUid() { + return uid; + } + + public void addBloc(Block b) { + this.blocs.add(b); + } + + public Cluster getParent() { + return parent; + } + + public Collection getContents() { + return Collections.unmodifiableCollection(blocs); + } + + public Block getBlock(int uid) { + for (Block b : blocs) { + if (b.getUid() == uid) { + return b; + } + } + for (Cluster sub : children) { + final Block result = sub.getBlock(uid); + if (result != null) { + return result; + } + } + return null; + } + + public Point2D getPosition() { + return new Point2D.Double(x, y); + } + + public Dimension2D getSize() { + return new Dimension2DDouble(width, height); + } + + public final void setX(double x) { + this.x = x; + } + + public final void setY(double y) { + this.y = y; + } + + public final void setWidth(double width) { + this.width = width; + } + + public final void setHeight(double height) { + this.height = height; + } + + +} diff --git a/src/net/sourceforge/plantuml/posimo/Clusterable.java b/src/net/sourceforge/plantuml/posimo/Clusterable.java new file mode 100644 index 000000000..dde949179 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Clusterable.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +public interface Clusterable extends Positionable { + + public Cluster getParent(); + +} diff --git a/src/net/sourceforge/plantuml/posimo/Decor.java b/src/net/sourceforge/plantuml/posimo/Decor.java new file mode 100644 index 000000000..c1f983121 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Decor.java @@ -0,0 +1,43 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public interface Decor { + + void drawDecor(UGraphic ug, Point2D start, double direction); +} diff --git a/src/net/sourceforge/plantuml/posimo/DecorInterfaceProvider.java b/src/net/sourceforge/plantuml/posimo/DecorInterfaceProvider.java new file mode 100644 index 000000000..48dfcc93a --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/DecorInterfaceProvider.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.cucadiagram.LinkStyle; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class DecorInterfaceProvider implements Decor { + + private final double radius = 5; + private final double radius2 = 9; + private final LinkStyle style; + + // private final double distanceCircle = 16; + + public DecorInterfaceProvider(LinkStyle style) { + if (style != LinkStyle.INTERFACE_PROVIDER && style != LinkStyle.INTERFACE_USER) { + throw new IllegalArgumentException(); + } + this.style = style; + } + + public void drawDecor(UGraphic ug, Point2D start, double direction) { + final double cornerX = start.getX() - radius; + final double cornerY = start.getY() - radius; + final double cornerX2 = start.getX() - radius2 - 0 * Math.sin(direction * Math.PI / 180.0); + final double cornerY2 = start.getY() - radius2 - 0 * Math.cos(direction * Math.PI / 180.0); + + if (style == LinkStyle.INTERFACE_USER) { + direction += 180; + } + if (direction >= 360) { + direction -= 360; + } + + final UEllipse arc = new UEllipse(2 * radius2, 2 * radius2, direction + 15, 180 - 30); + final UStroke old = ug.getParam().getStroke(); + ug.getParam().setStroke(new UStroke(1.5)); + ug.draw(cornerX2, cornerY2, arc); + ug.draw(cornerX, cornerY, new UEllipse(2 * radius, 2 * radius)); + ug.getParam().setStroke(old); + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/DotPath.java b/src/net/sourceforge/plantuml/posimo/DotPath.java new file mode 100644 index 000000000..4a46f4399 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/DotPath.java @@ -0,0 +1,285 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import net.sourceforge.plantuml.asciiart.BasicCharArea; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DotPath implements UShape { + + static class TriPoints { + public TriPoints(String p1, String p2, String p, double deltaY) { + final StringTokenizer st1 = new StringTokenizer(p1, ","); + x1 = Double.parseDouble(st1.nextToken()); + y1 = Double.parseDouble(st1.nextToken()) + deltaY; + final StringTokenizer st2 = new StringTokenizer(p2, ","); + x2 = Double.parseDouble(st2.nextToken()); + y2 = Double.parseDouble(st2.nextToken()) + deltaY; + final StringTokenizer st = new StringTokenizer(p, ","); + x = Double.parseDouble(st.nextToken()); + y = Double.parseDouble(st.nextToken()) + deltaY; + } + + private final double x1; + private final double y1; + private final double x2; + private final double y2; + private final double x; + private final double y; + +// @Override +// public String toString() { +// return "[" + x1 + "," + y1 + " " + x2 + "," + y2 + " " + x + "," + y + "]"; +// } + } + + private final List beziers = new ArrayList(); + //private final String print; + + public Point2D getStartPoint() { + return beziers.get(0).getP1(); + } + + public DotPath() { + this(new ArrayList()); + } + + public Point2D getEndPoint() { + return beziers.get(beziers.size() - 1).getP2(); + } + + public DotPath addBefore(CubicCurve2D.Double before) { + final List copy = new ArrayList(beziers); + copy.add(0, before); + return new DotPath(copy); + } + + public DotPath addAfter(CubicCurve2D.Double after) { + final List copy = new ArrayList(beziers); + copy.add(after); + return new DotPath(copy); + } + + public DotPath addAfter(DotPath other) { + final List copy = new ArrayList(beziers); + copy.addAll(other.beziers); + return new DotPath(copy); + } + + private DotPath(List beziers) { + this.beziers.addAll(beziers); + //this.print = super.toString(); + } + +// @Override +// public String toString() { +// return print; +// } + + public DotPath(String init, double deltaY) { + if (init.startsWith("M") == false) { + throw new IllegalArgumentException(); + } + final int posC = init.indexOf("C"); + if (posC == -1) { + throw new IllegalArgumentException(); + } + final StringTokenizer st = new StringTokenizer(init.substring(1, posC), ","); + final double startX = Double.parseDouble(st.nextToken()); + final double startY = Double.parseDouble(st.nextToken()) + deltaY; + + final StringTokenizer st2 = new StringTokenizer(init.substring(posC + 1), " "); + final List triPoints = new ArrayList(); + while (st2.hasMoreTokens()) { + final String p1 = st2.nextToken(); + final String p2 = st2.nextToken(); + final String p = st2.nextToken(); + triPoints.add(new TriPoints(p1, p2, p, deltaY)); + } + double x = startX; + double y = startY; + for (TriPoints p : triPoints) { + final CubicCurve2D.Double bezier = new CubicCurve2D.Double(x, y, p.x1, p.y1, p.x2, p.y2, p.x, p.y); + beziers.add(bezier); + x = p.x; + y = p.y; + } + // this.print = triPoints.toString(); + } + + public Map somePoints() { + final Map result = new HashMap(); + for (CubicCurve2D.Double bez : beziers) { + final CubicCurve2D.Double left = new CubicCurve2D.Double(); + final CubicCurve2D.Double right = new CubicCurve2D.Double(); + bez.subdivide(left, right); + result.put(left.getP1(), BezierUtils.getStartingAngle(left)); + result.put(left.getP2(), BezierUtils.getEndingAngle(left)); + result.put(right.getP1(), BezierUtils.getStartingAngle(right)); + result.put(right.getP2(), BezierUtils.getEndingAngle(right)); + } + return result; + } + +// public void drawOld(Graphics2D g2d, double x, double y) { +// for (CubicCurve2D.Double bez : beziers) { +// bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2, y +// + bez.ctrly2, x + bez.x2, y + bez.y2); +// g2d.draw(bez); +// } +// } +// + public void draw(Graphics2D g2d, double x, double y) { + final GeneralPath p = new GeneralPath(); + for (CubicCurve2D.Double bez : beziers) { + bez = new CubicCurve2D.Double(x + bez.x1, y + bez.y1, x + bez.ctrlx1, y + bez.ctrly1, x + bez.ctrlx2, y + + bez.ctrly2, x + bez.x2, y + bez.y2); + p.append(bez, true); + } + g2d.draw(p); + } + + public Point2D getFrontierIntersection(Shape shape, Rectangle2D... notIn) { + final List all = new ArrayList(beziers); + for (int i = 0; i < 8; i++) { + for (CubicCurve2D.Double immutable : all) { + if (contains(immutable, notIn)) { + continue; + } + final CubicCurve2D.Double bez = new CubicCurve2D.Double(); + bez.setCurve(immutable); + if (BezierUtils.isCutting(bez, shape)) { + while (BezierUtils.dist(bez) > 1.0) { + BezierUtils.shorten(bez, shape); + } + final Point2D.Double result = new Point2D.Double((bez.x1 + bez.x2) / 2, (bez.y1 + bez.y2) / 2); + if (contains(result, notIn) == false) { + return result; + } + } + } + cutAllCubic(all); + } + throw new IllegalArgumentException("shape=" + shape); + } + + private void cutAllCubic(List all) { + final List tmp = new ArrayList(all); + all.clear(); + for (CubicCurve2D.Double bez : tmp) { + final CubicCurve2D.Double left = new CubicCurve2D.Double(); + final CubicCurve2D.Double right = new CubicCurve2D.Double(); + bez.subdivide(left, right); + all.add(left); + all.add(right); + } + } + + static private boolean contains(Point2D.Double point, Rectangle2D... rects) { + for (Rectangle2D r : rects) { + if (r.contains(point)) { + return true; + } + } + return false; + } + + static private boolean contains(CubicCurve2D.Double cubic, Rectangle2D... rects) { + for (Rectangle2D r : rects) { + if (r.contains(cubic.getP1()) && r.contains(cubic.getP2())) { + return true; + } + } + return false; + } + + public DotPath manageRect(Rectangle2D start, Rectangle2D end) { + final List list = new ArrayList(this.beziers); + while (true) { + if (BezierUtils.isCutting(list.get(0), start) == false) { + throw new IllegalStateException(); + } + if (BezierUtils.dist(list.get(0)) <= 1.0) { + break; + } + final CubicCurve2D.Double left = new CubicCurve2D.Double(); + final CubicCurve2D.Double right = new CubicCurve2D.Double(); + list.get(0).subdivide(left, right); + list.set(0, left); + list.add(1, right); + if (BezierUtils.isCutting(list.get(1), start)) { + list.remove(0); + } + } + return new DotPath(list); + } + + public Point2D getFrontierIntersection(Positionable p) { + return getFrontierIntersection(PositionableUtils.convert(p)); + } + + public void draw(BasicCharArea area, double pixelXPerChar, double pixelYPerChar) { + for (CubicCurve2D.Double bez : beziers) { + if (bez.x1 == bez.x2) { + area.drawVLine('|', (int) (bez.x1 / pixelXPerChar), (int) (bez.y1 / pixelYPerChar), + (int) (bez.y2 / pixelYPerChar)); + } else if (bez.y1 == bez.y2) { + area.drawHLine('-', (int) (bez.y1 / pixelYPerChar), (int) (bez.x1 / pixelXPerChar), + (int) (bez.x2 / pixelXPerChar)); + } else { + throw new UnsupportedOperationException("bez=" + toString(bez)); + } + } + } + + private String toString(CubicCurve2D.Double c) { + return "(" + c.x1 + "," + c.y1 + ") " + "(" + c.ctrlx1 + "," + c.ctrly1 + ") " + "(" + c.ctrlx2 + "," + + c.ctrly2 + ") " + "(" + c.x2 + "," + c.y2 + ") "; + + } + + +} diff --git a/src/net/sourceforge/plantuml/posimo/DotxMaker.java b/src/net/sourceforge/plantuml/posimo/DotxMaker.java new file mode 100644 index 000000000..0e1e76199 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/DotxMaker.java @@ -0,0 +1,114 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.util.Collection; + +public class DotxMaker { + + private final Cluster root; + private final Collection paths; + + public DotxMaker(Cluster root, Collection paths) { + this.root = root; + this.paths = paths; + } + + public String createDotString() { + final StringBuilder sb = new StringBuilder(); + sb.append("digraph unix {"); + sb.append("compound=true;"); + + printCluster(sb, root); + + for (Path p : paths) { + sb.append(getPathString(p) + ";"); + } + + sb.append("}"); + + return sb.toString(); + } + + private void printCluster(StringBuilder sb, Cluster cl) { + if (cl.getContents().size() == 0) { + throw new IllegalStateException(cl.toString()); + } + for (Cluster sub : cl.getSubClusters()) { + sb.append("subgraph cluster" + sub.getUid() + " {"); + printCluster(sb, sub); + sb.append("}"); + + } + for (Block b : cl.getContents()) { + sb.append("b" + b.getUid() + getNodeAttibute(b) + ";"); + } + + } + + private String getPathString(Path p) { + if (p == null) { + throw new IllegalArgumentException(); + } + final StringBuilder sb = new StringBuilder("b" + p.getStart().getUid() + " -> b" + p.getEnd().getUid()); + //sb.append(" [dir=none, arrowhead=none, headclip=false, tailclip=false"); + sb.append(" [dir=none, arrowhead=none, headclip=true, tailclip=true"); + if (p.getLabel() == null) { + sb.append("]"); + } else { + final Dimension2D size = p.getLabel().getSize(); + sb.append(", label=<
>]"); + } + + if (p.getLength() <= 1) { + sb.append("{rank=same; b" + p.getStart().getUid() + "; b" + p.getEnd().getUid() + "}"); + } + + return sb.toString(); + } + + private String getNodeAttibute(Block b) { + final StringBuilder sb = new StringBuilder("["); + sb.append("label=\"\","); + sb.append("fixedsize=true,"); + sb.append("width=" + b.getSize().getWidth() / 72.0 + ","); + sb.append("height=" + b.getSize().getHeight() / 72.0 + ","); + sb.append("shape=rect"); + sb.append("]"); + return sb.toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java b/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java new file mode 100644 index 000000000..1d69a87db --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java @@ -0,0 +1,156 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Color; +import java.awt.geom.Dimension2D; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.dot.PlayField; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicUtils; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class EntityImageBlock implements IEntityImageBlock { + + private final IEntity entity; + private final ISkinParam param; + private final Rose rose; + private final int margin = 6; + private final TextBlock name; + private final Collection links; + + private PlayField playField; + private Frame frame; + + public EntityImageBlock(IEntity entity, Rose rose, ISkinParam param, Collection links) { + this.entity = entity; + this.param = param; + this.rose = rose; + this.links = links; + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), param + .getFont(FontParam.CLASS), Color.BLACK, HorizontalAlignement.CENTER); + + } + + public Dimension2D getDimension(StringBounder stringBounder) { + initPlayField(stringBounder); + Dimension2D dim; + if (playField == null) { + dim = name.calculateDimension(stringBounder); + } else { + try { + dim = playField.solve(); + // final double frameWidth = + // frame.getPreferredWidth(stringBounder); + final double frameHeight = frame.getPreferredHeight(stringBounder); + dim = Dimension2DDouble.delta(dim, 0, frameHeight); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(); + } + } + return Dimension2DDouble.delta(dim, margin * 2); + } + + private void initPlayField(StringBounder stringBounder) { + if (playField != null || entity.getParent() == null || entity.getType() != EntityType.GROUP) { + return; + } + this.playField = new PlayField(param); + final Collection entities = new ArrayList(); + for (IEntity ent : entity.getParent().entities().values()) { + //entities.add(EntityUtils.withNoParent(ent)); + entities.add(ent); + } + playField.initInternal(entities, links, stringBounder); + + this.frame = new Frame(StringUtils.getWithNewlines(entity.getDisplay()), Color.BLACK, param + .getFont(FontParam.CLASS), rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + + } + + public void drawU(UGraphic ug, double xTheoricalPosition, double yTheoricalPosition, double marginWidth, + double marginHeight) { + final Dimension2D dim = getDimension(ug.getStringBounder()); + + final double widthTotal = dim.getWidth() + 2 * marginWidth; + final double heightTotal = dim.getHeight() + 2 * marginHeight; + final URectangle rect = new URectangle(widthTotal, heightTotal); + + //if (entity.getParent() == null) { + if (entity.getType() != EntityType.GROUP) { + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.classBackground).getColor()); + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + ug.draw(xTheoricalPosition - marginWidth, yTheoricalPosition - marginHeight, rect); + name.drawU(ug, xTheoricalPosition + margin, yTheoricalPosition + margin); + } else { + final Frame frame = new Frame(StringUtils.getWithNewlines(entity.getDisplay()), Color.BLACK, param + .getFont(FontParam.CLASS), rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.background).getColor()); + ug.getParam().setColor(null); + ug.draw(xTheoricalPosition - marginWidth, yTheoricalPosition - marginWidth, rect); + + final double oldX = ug.getTranslateX(); + final double oldY = ug.getTranslateY(); + ug.translate(xTheoricalPosition - marginWidth, yTheoricalPosition - marginHeight); + frame.drawU(ug, new Dimension2DDouble(widthTotal, heightTotal), null); + // ug.translate(-xTheoricalPosition + marginWidth, + // -yTheoricalPosition + marginHeight); + ug.setTranslate(oldX, oldY); + + playField.drawInternal(UGraphicUtils.translate(ug, xTheoricalPosition + margin, yTheoricalPosition + margin + + frame.getPreferredHeight(ug.getStringBounder()))); + } + } +} diff --git a/src/net/sourceforge/plantuml/posimo/EntityImageClass2.java b/src/net/sourceforge/plantuml/posimo/EntityImageClass2.java new file mode 100644 index 000000000..26da07835 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/EntityImageClass2.java @@ -0,0 +1,163 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5183 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Color; +import java.awt.geom.Dimension2D; +import java.util.Collection; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.graph.MethodsOrFieldsArea; +import net.sourceforge.plantuml.graphic.CircledCharacter; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class EntityImageClass2 extends AbstractEntityImage2 { + + final private TextBlock name; + final private MethodsOrFieldsArea methods; + final private MethodsOrFieldsArea fields; + final private CircledCharacter circledCharacter; + + // private final int xMargin = 0; + // private final int yMargin = 0; + // public static final int MARGIN = 20; + + public EntityImageClass2(IEntity entity, Rose rose, ISkinParam skinParam, Collection links) { + super(entity); + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), getFont14(), Color.BLACK, + HorizontalAlignement.CENTER); + this.methods = new MethodsOrFieldsArea(entity.methods2(), getFont14()); + this.fields = new MethodsOrFieldsArea(entity.fields2(), getFont14()); + + circledCharacter = getCircledCharacter(entity); + } + + private CircledCharacter getCircledCharacter(IEntity entity) { + // if (entity.getStereotype() != null) { + // return new CircledCharacter(entity.getStereotype().getCharacter(), + // font, entity.getStereotype().getColor(), + // red, Color.BLACK); + // } + final double radius = 10; + if (entity.getType() == EntityType.ABSTRACT_CLASS) { + return new CircledCharacter('A', radius, getFont17(), getBlue(), getRed(), Color.BLACK); + } + if (entity.getType() == EntityType.CLASS) { + return new CircledCharacter('C', radius, getFont17(), getGreen(), getRed(), Color.BLACK); + } + if (entity.getType() == EntityType.INTERFACE) { + return new CircledCharacter('I', radius, getFont17(), getViolet(), getRed(), Color.BLACK); + } + if (entity.getType() == EntityType.ENUM) { + return new CircledCharacter('E', radius, getFont17(), getRose(), getRed(), Color.BLACK); + } + assert false; + return null; + } + + @Override + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D dimName = getNameDimension(stringBounder); + final Dimension2D dimMethods = methods.calculateDimension(stringBounder); + final Dimension2D dimFields = fields.calculateDimension(stringBounder); + final double width = Math.max(Math.max(dimMethods.getWidth(), dimFields.getWidth()), dimName.getWidth()); + final double height = dimMethods.getHeight() + dimFields.getHeight() + dimName.getHeight(); + return new Dimension2DDouble(width, height); + } + + private Dimension2D getNameDimension(StringBounder stringBounder) { + final Dimension2D nameDim = name.calculateDimension(stringBounder); + if (circledCharacter == null) { + return nameDim; + } + return new Dimension2DDouble(nameDim.getWidth() + getCircledWidth(stringBounder), Math.max(nameDim.getHeight(), + circledCharacter.getPreferredHeight(stringBounder))); + } + + private double getCircledWidth(StringBounder stringBounder) { + if (circledCharacter == null) { + return 0; + } + return circledCharacter.getPreferredWidth(stringBounder) + 3; + } + + public void drawU(UGraphic ug, double xTheoricalPosition, double yTheoricalPosition, double marginWidth, + double marginHeight) { + final Dimension2D dimTotal = getDimension(ug.getStringBounder()); + final Dimension2D dimName = getNameDimension(ug.getStringBounder()); + final Dimension2D dimFields = fields.calculateDimension(ug.getStringBounder()); + + final double widthTotal = dimTotal.getWidth(); + final double heightTotal = dimTotal.getHeight(); + final URectangle rect = new URectangle(widthTotal, heightTotal); + + ug.getParam().setColor(getRed()); + ug.getParam().setBackcolor(getYellow()); + + double x = xTheoricalPosition; + double y = yTheoricalPosition; + ug.draw(x, y, rect); + + if (circledCharacter != null) { + circledCharacter.drawU(ug, x, y); + x += circledCharacter.getPreferredWidth(ug.getStringBounder()); + } + name.drawU(ug, x, y); + + y += dimName.getHeight(); + + x = xTheoricalPosition; + ug.getParam().setColor(getRed()); + ug.draw(x, y, new ULine(widthTotal, 0)); + fields.draw(ug, x, y); + + y += dimFields.getHeight(); + ug.getParam().setColor(getRed()); + ug.draw(x, y, new ULine(widthTotal, 0)); + + methods.draw(ug, x, y); + } +} diff --git a/src/net/sourceforge/plantuml/posimo/Frame.java b/src/net/sourceforge/plantuml/posimo/Frame.java new file mode 100644 index 000000000..d94b806f5 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Frame.java @@ -0,0 +1,107 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class Frame implements Component { + + private final List name; + private final Color textColor; + private final Color lineColor; + private final Font font; + + public Frame(List name, Color textColor, Font font, Color lineColor) { + this.name = name; + this.textColor = textColor; + this.lineColor = lineColor; + this.font = font; + } + + public void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + ug.getParam().setColor(lineColor); + ug.getParam().setBackcolor(null); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight())); + + final TextBlock textBlock = createTextBloc(); + textBlock.drawU(ug, 2, 2); + + final Dimension2D textDim = getTextDim(ug.getStringBounder()); + final double x = textDim.getWidth() + 6; + final double y = textDim.getHeight() + 6; + final UPolygon poly = new UPolygon(); + poly.addPoint(x, 0); + poly.addPoint(x, y - 6); + poly.addPoint(x - 6, y); + poly.addPoint(0, y); + poly.addPoint(0, 0); + ug.getParam().setColor(lineColor); + ug.draw(0, 0, poly); + + } + + public double getPreferredHeight(StringBounder stringBounder) { + final Dimension2D dim = getTextDim(stringBounder); + return dim.getHeight() + 8; + } + + public double getPreferredWidth(StringBounder stringBounder) { + final Dimension2D dim = getTextDim(stringBounder); + return dim.getWidth() + 8; + } + + private Dimension2D getTextDim(StringBounder stringBounder) { + final TextBlock bloc = createTextBloc(); + return bloc.calculateDimension(stringBounder); + } + + private TextBlock createTextBloc() { + final TextBlock bloc = TextBlockUtils.create(name, font, textColor, HorizontalAlignement.LEFT); + return bloc; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java b/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java new file mode 100644 index 000000000..9a5914772 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/GraphvizSolverB.java @@ -0,0 +1,248 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.cucadiagram.dot.Graphviz; +import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils; + +public class GraphvizSolverB { + + static private void traceDotString(String dotString) throws IOException { + final File f = new File("dottmpfile" + UniqueSequence.getValue() + ".tmp"); + PrintWriter pw = null; + try { + pw = new PrintWriter(new FileWriter(f)); + pw.print(dotString); + Log.info("Creating file " + f); + } finally { + if (pw != null) { + pw.close(); + } + } + } + + static private void traceSvgString(String svg) throws IOException { + final File f = new File("svgtmpfile" + UniqueSequence.getValue() + ".svg"); + PrintWriter pw = null; + try { + pw = new PrintWriter(new FileWriter(f)); + pw.print(svg); + Log.info("Creating file " + f); + } finally { + if (pw != null) { + pw.close(); + } + } + } + + public Dimension2D solve(Cluster root, Collection paths) throws IOException, InterruptedException { + final String dotString = new DotxMaker(root, paths).createDotString(); + + if (OptionFlags.getInstance().isKeepTmpFiles()) { + traceDotString(dotString); + } + + // System.err.println("dotString=" + dotString); + + // exportPng(dotString, new File("png", "test1.png")); + + final Graphviz graphviz = GraphvizUtils.create(dotString, "svg"); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + graphviz.createPng(baos); + baos.close(); + final byte[] result = baos.toByteArray(); + final String s = new String(result, "UTF-8"); + // System.err.println("result=" + s); + + if (OptionFlags.getInstance().isKeepTmpFiles()) { + traceSvgString(s); + } + + final Pattern pGraph = Pattern.compile("(?m)\\" + start + ""); + if (p1 == -1) { + throw new IllegalStateException(); + } + final List pointsList = extractPointsList(s, p1); + b.setX(getMinX(pointsList)); + b.setY(getMinY(pointsList) + height); + } + + for (Cluster cl : root.getSubClusters()) { + final String start = "cluster" + cl.getUid(); + final int p1 = s.indexOf("" + start + ""); + if (p1 == -1) { + throw new IllegalStateException(); + } + final List pointsList = extractPointsList(s, p1); + cl.setX(getMinX(pointsList)); + cl.setY(getMinY(pointsList) + height); + final double w = getMaxX(pointsList) - getMinX(pointsList); + final double h = getMaxY(pointsList) - getMinY(pointsList); + cl.setHeight(h); + cl.setWidth(w); + } + + for (Path p : paths) { + final String start = "b" + p.getStart().getUid(); + final String end = "b" + p.getEnd().getUid(); + final String searched = "" + start + "->" + end + ""; + final int p1 = s.indexOf(searched); + if (p1 == -1) { + throw new IllegalStateException(searched); + } + final int p2 = s.indexOf(" d=\"", p1); + final int p3 = s.indexOf("\"", p2 + " d=\"".length()); + final String points = s.substring(p2 + " d=\"".length(), p3); + p.setDotPath(new DotPath(points, height)); + + // System.err.println("pointsList=" + pointsList); + if (p.getLabel() != null) { + final List pointsList = extractPointsList(s, p1); + p.setLabelPosition(getMinX(pointsList), getMinY(pointsList) + height); + } + + } + + return new Dimension2DDouble(width, height); + } + + private List extractPointsList(final String svg, final int starting) { + final String pointsString = "points=\""; + final int p2 = svg.indexOf(pointsString, starting); + final int p3 = svg.indexOf("\"", p2 + pointsString.length()); + final String points = svg.substring(p2 + pointsString.length(), p3); + final List pointsList = getPoints(points); + return pointsList; + } + + private double getMaxX(List points) { + double result = points.get(0).x; + for (int i = 1; i < points.size(); i++) { + if (points.get(i).x > result) { + result = points.get(i).x; + } + } + return result; + } + + private double getMinX(List points) { + double result = points.get(0).x; + for (int i = 1; i < points.size(); i++) { + if (points.get(i).x < result) { + result = points.get(i).x; + } + } + return result; + } + + private double getMaxY(List points) { + double result = points.get(0).y; + for (int i = 1; i < points.size(); i++) { + if (points.get(i).y > result) { + result = points.get(i).y; + } + } + return result; + } + + private double getMinY(List points) { + double result = points.get(0).y; + for (int i = 1; i < points.size(); i++) { + if (points.get(i).y < result) { + result = points.get(i).y; + } + } + return result; + } + + private List getPoints(String points) { + final List result = new ArrayList(); + final StringTokenizer st = new StringTokenizer(points, " "); + while (st.hasMoreTokens()) { + final String t = st.nextToken(); + final StringTokenizer st2 = new StringTokenizer(t, ","); + final double x = Double.parseDouble(st2.nextToken()); + final double y = Double.parseDouble(st2.nextToken()); + result.add(new Point2D.Double(x, y)); + } + return result; + } + + private void exportPng(final String dotString, File f) throws IOException, InterruptedException { + final Graphviz graphviz = GraphvizUtils.create(dotString, "png"); + final OutputStream os = new FileOutputStream(f); + graphviz.createPng(os); + os.close(); + } + + private Path getPath(Collection paths, int start, int end) { + for (Path p : paths) { + if (p.getStart().getUid() == start && p.getEnd().getUid() == end) { + return p; + } + } + throw new IllegalArgumentException(); + + } +} diff --git a/src/net/sourceforge/plantuml/posimo/IEntityImageBlock.java b/src/net/sourceforge/plantuml/posimo/IEntityImageBlock.java new file mode 100644 index 000000000..616786129 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/IEntityImageBlock.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public interface IEntityImageBlock { + + Dimension2D getDimension(StringBounder stringBounder); + + void drawU(UGraphic ug, double xTheoricalPosition, double yTheoricalPosition, double marginWidth, + double marginHeight); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/posimo/Label.java b/src/net/sourceforge/plantuml/posimo/Label.java new file mode 100644 index 000000000..2a0f7b76d --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Label.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.Dimension2DDouble; + +public class Label implements Positionable { + + private double width; + private double height; + private double x; + private double y; + + public Label(double width, double height) { + this.width = width; + this.height = height; + } + + public final void setCenterX(double center) { + this.x = center - width / 2; + } + + public final void setCenterY(double center) { + this.y = center - height / 2; + } + + public Point2D getPosition() { + return new Point2D.Double(x, y); + } + + public Dimension2D getSize() { + return new Dimension2DDouble(width, height); + } + + public final void setWidth(double width) { + this.width = width; + } + + public final void setHeight(double height) { + this.height = height; + } + + public final void setX(double x) { + this.x = x; + } + + public final void setY(double y) { + this.y = y; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/LabelImage.java b/src/net/sourceforge/plantuml/posimo/LabelImage.java new file mode 100644 index 000000000..e5a2a0886 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/LabelImage.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class LabelImage { + + // private final Entity entity; + final private ISkinParam param; + final private Rose rose; + final private TextBlock name; + + public LabelImage(Link link, Rose rose, ISkinParam param) { + if (link == null) { + throw new IllegalArgumentException(); + } + // this.entity = entity; + this.param = param; + this.rose = rose; + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(link.getLabel()), param.getFont(FontParam.CLASS), + Color.BLACK, HorizontalAlignement.CENTER); + } + + public Dimension2D getDimension(StringBounder stringBounder) { + final Dimension2D dim = name.calculateDimension(stringBounder); + return dim; + //return Dimension2DDouble.delta(dim, 2 * margin); + } + + public void drawU(UGraphic ug, double x, double y) { + // final Dimension2D dim = getDimension(ug.getStringBounder()); + // ug.getParam().setBackcolor(rose.getHtmlColor(param, + // ColorParam.classBackground).getColor()); + // ug.getParam().setColor(rose.getHtmlColor(param, + // ColorParam.classBorder).getColor()); + // ug.draw(x, y, new URectangle(dim.getWidth(), dim.getHeight())); + name.drawU(ug, x, y); + } +} diff --git a/src/net/sourceforge/plantuml/posimo/MargedBlock.java b/src/net/sourceforge/plantuml/posimo/MargedBlock.java new file mode 100644 index 000000000..5694c395c --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/MargedBlock.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public class MargedBlock { + + private final Block block; + private final IEntityImageBlock imageBlock; + private final int marginDecorator; + private final Dimension2D imageDimension; + + static private int uid = 1; + + public MargedBlock(StringBounder stringBounder, IEntityImageBlock imageBlock, int marginDecorator) { + this.imageBlock = imageBlock; + this.marginDecorator = marginDecorator; + this.imageDimension = imageBlock.getDimension(stringBounder); + this.block = new Block(uid++, imageDimension.getWidth() + 2 + * marginDecorator, imageDimension.getHeight() + 2 + * marginDecorator); + } + + public Block getBlock() { + return block; + } + + public int getMarginDecorator() { + return marginDecorator; + } + + public IEntityImageBlock getImageBlock() { + return imageBlock; + } + + public Positionable getImagePosition() { + return new Positionable() { + + public Dimension2D getSize() { + return imageDimension; + } + + public Point2D getPosition() { + Point2D pos = block.getPosition(); + return new Point2D.Double(pos.getX() + marginDecorator, pos + .getY() + + marginDecorator); + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/Mirror.java b/src/net/sourceforge/plantuml/posimo/Mirror.java new file mode 100644 index 000000000..bf1ff8f0b --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Mirror.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +public class Mirror { + + private final double max; + + public Mirror(double max) { + this.max = max; + } + + public double getMirrored(double v) { + if (v < 0 || v > max) { + throw new IllegalArgumentException(); + } + //return v; + return max - v; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/Path.java b/src/net/sourceforge/plantuml/posimo/Path.java new file mode 100644 index 000000000..b053331ca --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Path.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +public class Path { + + private final Label label; + private final Block start; + private final Block end; + private final int length; + private DotPath dotPath; + + public Path(Block start, Block end, Label label) { + this(start, end, label, 2); + } + + public Path(Block start, Block end, Label label, int length) { + if (start == null || end == null) { + throw new IllegalArgumentException(); + } + this.start = start; + this.end = end; + this.label = label; + this.length = length; + } + + public final Label getLabel() { + return label; + } + + public final Block getStart() { + return start; + } + + public final Block getEnd() { + return end; + } + + public void setLabelPositionCenter(double labelX, double labelY) { + label.setCenterX(labelX); + label.setCenterY(labelY); + } + + public void setLabelPosition(double x, double y) { + label.setX(x); + label.setY(y); + } + + public void setDotPath(DotPath dotPath) { + this.dotPath = dotPath; + + } + + public final DotPath getDotPath() { + return dotPath; + } + + public int getLength() { + return length; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/PathDrawer.java b/src/net/sourceforge/plantuml/posimo/PathDrawer.java new file mode 100644 index 000000000..c5ce66020 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/PathDrawer.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public interface PathDrawer { + + public void drawPathBefore(UGraphic ug, Positionable start, Positionable end, Path path); + + public void drawPathAfter(UGraphic ug, Positionable start, Positionable end, Path path); + +} diff --git a/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java b/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java new file mode 100644 index 000000000..b673fd0ab --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java @@ -0,0 +1,352 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.Collection; +import java.util.Map; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkStyle; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class PathDrawerInterface implements PathDrawer { + + private final Rose rose; + private final ISkinParam param; + private final LinkType linkType; + + public static PathDrawerInterface create(Rose rose, ISkinParam param, LinkType linkType) { + return new PathDrawerInterface(rose, param, linkType); + } + + private PathDrawerInterface(Rose rose, ISkinParam param, LinkType linkType) { + this.rose = rose; + this.param = param; + this.linkType = linkType; + } + + public void drawPathBefore(UGraphic ug, Positionable start, Positionable end, Path path) { +//// final DotPath dotPath = path.getDotPath(); +//// goDash(ug); +//// ug.draw(0, 0, dotPath); +//// noDash(ug); + } + + private void noDash(UGraphic ug) { + ug.getParam().setStroke(new UStroke()); + } + + private void goDash(UGraphic ug) { + ug.getParam().setStroke(new UStroke(8, 1.0)); + } + + public void drawPathAfter(UGraphic ug, Positionable start, Positionable end, Path path) { + DotPath dotPath = path.getDotPath(); + + final Rectangle2D startRect = PositionableUtils.convert(start); + final double xstartCenter = startRect.getCenterX(); + final double ystartCenter = startRect.getCenterY(); + final Rectangle2D endRect = PositionableUtils.convert(end); + final double xendCenter = endRect.getCenterX(); + final double yendCenter = endRect.getCenterY(); + + final Point2D startCenter = new Point2D.Double(xstartCenter, ystartCenter); + final Point2D startPoint = dotPath.getStartPoint(); + final Point2D endPoint = dotPath.getEndPoint(); + final Point2D p1 = BezierUtils.intersect(new Line2D.Double(startPoint, startCenter), startRect); + final Point2D endCenter = new Point2D.Double(xendCenter, yendCenter); + final Point2D p2 = BezierUtils.intersect(new Line2D.Double(endPoint, endCenter), endRect); + + + CubicCurve2D.Double after = null; + + if (linkType.getDecor1() == LinkDecor.SQUARRE) { + drawSquare(ug, p1.getX(), p1.getY()); + } else { + if (linkType.getDecor1() == LinkDecor.EXTENDS) { + final Point2D middle = drawExtends(ug, p2.getX(), p2.getY(), endPoint); + after = getLine(endPoint, middle); + } else if (linkType.getDecor1() == LinkDecor.AGREGATION) { + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.background).getColor()); + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + final Point2D middle = drawDiamond(ug, p2.getX(), p2.getY(), endPoint); + after = getLine(endPoint, middle); + } else if (linkType.getDecor1() == LinkDecor.COMPOSITION) { + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + ug.getParam().setColor(null); + final Point2D middle = drawDiamond(ug, p2.getX(), p2.getY(), endPoint); + after = getLine(endPoint, middle); + } else if (linkType.getDecor1() == LinkDecor.NONE) { + after = getLine(endPoint, p2); + } else if (linkType.getDecor1() == LinkDecor.ARROW) { + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + final Point2D middle = drawArrow(ug, p2.getX(), p2.getY(), endPoint); + after = getLine(endPoint, middle); + } + } + if (after != null) { + dotPath = dotPath.addAfter(after); + } + + + CubicCurve2D.Double before = null; + + if (linkType.getDecor2() == LinkDecor.SQUARRE) { + drawSquare(ug, p2.getX(), p2.getY()); + } else { + if (linkType.getDecor2() == LinkDecor.EXTENDS) { + final Point2D middle = drawExtends(ug, p1.getX(), p1.getY(), + startPoint); + before = getLine(middle, startPoint); + } else if (linkType.getDecor2() == LinkDecor.AGREGATION) { + ug.getParam().setBackcolor( + rose.getHtmlColor(param, ColorParam.background) + .getColor()); + ug.getParam().setColor( + rose.getHtmlColor(param, ColorParam.classBorder) + .getColor()); + final Point2D middle = drawDiamond(ug, p1.getX(), p1.getY(), startPoint); + before = getLine(middle, startPoint); + } else if (linkType.getDecor2() == LinkDecor.COMPOSITION) { + ug.getParam().setBackcolor( + rose.getHtmlColor(param, ColorParam.classBorder) + .getColor()); + ug.getParam().setColor(null); + final Point2D middle = drawDiamond(ug, p1.getX(), p1.getY(), startPoint); + before = getLine(middle, startPoint); + } else if (linkType.getDecor2() == LinkDecor.NONE) { + before = getLine(p1, startPoint); + } else if (linkType.getDecor2() == LinkDecor.ARROW) { + ug.getParam().setBackcolor( + rose.getHtmlColor(param, ColorParam.classBorder) + .getColor()); + ug.getParam().setColor( + rose.getHtmlColor(param, ColorParam.classBorder) + .getColor()); + final Point2D middle = drawArrow(ug, p1.getX(), p1.getY(), startPoint); + before = getLine(middle, startPoint); + } + } + + if (before != null) { + dotPath = dotPath.addBefore(before); + } + + final LinkStyle style = linkType.getStyle(); + if (style == LinkStyle.INTERFACE_PROVIDER || style == LinkStyle.INTERFACE_USER) { + final Decor decor = new DecorInterfaceProvider(style); + final Map all = dotPath.somePoints(); + final Point2D p = getFarest(p1, p2, all.keySet()); + + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.background).getColor()); + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + + decor.drawDecor(ug, p, all.get(p)); + } + + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + if (linkType.isDashed()) { + goDash(ug); + } + ug.draw(0, 0, dotPath); + if (linkType.isDashed()) { + noDash(ug); + } + } + + private CubicCurve2D.Double getLine(final Point2D p1, Point2D p2) { + return new CubicCurve2D.Double(p1.getX(), p1 + .getY(), p1.getX(), p1.getY(), p2 + .getX(), p2.getY(), p2.getX(), p2.getY()); + } + + private static Point2D getFarest(Point2D p1, Point2D p2, Collection all) { + Point2D result = null; + double farest = 0; + for (Point2D p : all) { + if (result == null) { + result = p; + farest = p1.distanceSq(result) + p2.distanceSq(result); + continue; + } + final double candidat = p1.distanceSq(p) + p2.distanceSq(p); + if (candidat < farest) { + result = p; + farest = candidat; + } + } + if (result == null) { + throw new IllegalArgumentException(); + } + return result; + } + + private void drawSquare(UGraphic ug, double centerX, double centerY) { + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.classBackground).getColor()); + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + final double width = 10; + final double height = 10; + ug.draw(centerX - width / 2, centerY - height / 2, new URectangle(width, height)); + } + + private Point2D drawExtends(UGraphic ug, double x, double y, Point2D pathPoint) { + ug.getParam().setBackcolor(rose.getHtmlColor(param, ColorParam.background).getColor()); + ug.getParam().setColor(rose.getHtmlColor(param, ColorParam.classBorder).getColor()); + + final double width = 18; + final double height = 26; + + final double theta = Math.atan2(-pathPoint.getX() + x, pathPoint.getY() - y); + + final UPolygon triangle = new UPolygon(); + triangle.addPoint(0, 1); + triangle.addPoint(-width / 2, height); + triangle.addPoint(width / 2, height); + triangle.rotate(theta); + ug.draw(x, y, triangle); + + //ug.getParam().setColor(Color.BLACK); + final Point2D middle = BezierUtils.middle(triangle.getPoints().get(1), triangle.getPoints().get(2)); + middle.setLocation(middle.getX() + x, middle.getY() + y); + //drawLine2(ug, pathPoint, middle); +// return new CubicCurve2D.Double(middle.getX(), middle.getY(), middle.getX(), middle.getY(), +// pathPoint.getX(), pathPoint.getY(),pathPoint.getX(), pathPoint.getY()); + return middle; + } + +// private void drawLine(UGraphic ug, Point2D p1, Point2D p2) { +//// ug.getParam().setColor(Color.BLACK); +//// final ULine line = new ULine(p2.getX() - p1.getX(), p2.getY() - p1.getY()); +//// goDash(ug); +//// ug.draw(p1.getX(), p1.getY(), line); +//// noDash(ug); +// } + + + private Point2D drawDiamond(UGraphic ug, double x, double y, Point2D pathPoint) { + final double width = 10; + final double height = 14; + + final double theta = Math.atan2(-pathPoint.getX() + x, pathPoint.getY() - y); + + final UPolygon triangle = new UPolygon(); + triangle.addPoint(0, 0); + triangle.addPoint(-width / 2, height / 2); + triangle.addPoint(0, height); + triangle.addPoint(width / 2, height / 2); + triangle.rotate(theta); + ug.draw(x, y, triangle); + +// ug.getParam().setColor(Color.BLACK); + final Point2D middle = triangle.getPoints().get(2); + middle.setLocation(middle.getX() + x, middle.getY() + y); +// final ULine line = new ULine(pathPoint.getX() - middle.getX(), pathPoint.getY() - middle.getY()); +// ug.draw(middle.getX(), middle.getY(), line); + return middle; + + } + + private Point2D drawArrow(UGraphic ug, double x, double y, Point2D pathPoint) { + final double width = 16; + final double height = 16; + final double height2 = 7; + + final double theta = Math.atan2(-pathPoint.getX() + x, pathPoint.getY() - y); + + final UPolygon triangle = new UPolygon(); + triangle.addPoint(0, 0); + triangle.addPoint(-width / 2, height); + triangle.addPoint(0, height2); + triangle.addPoint(width / 2, height); + triangle.rotate(theta); + ug.draw(x, y, triangle); + +// ug.getParam().setColor(Color.BLACK); + final Point2D middle = triangle.getPoints().get(2); + middle.setLocation(middle.getX() + x, middle.getY() + y); +// drawLine(ug, pathPoint, middle); + return middle; + } + + private Point2D nullIfContained(Point2D p, Positionable start, Positionable end) { + if (PositionableUtils.contains(start, p)) { + return null; + } + if (PositionableUtils.contains(end, p)) { + return null; + } + return p; + } + + // private void drawPath(UGraphic ug, PointList points, Positionable start, + // Positionable end) { + // Decor decor = new DecorInterfaceProvider(); + // Point2D last = null; + // final int nb = 10; + // final double t1 = + // points.getIntersectionDouble(PositionableUtils.convert(start)); + // final double t2 = + // points.getIntersectionDouble(PositionableUtils.convert(end)); + // for (int i = 0; i <= nb; i++) { + // final double d = t1 + (t2 - t1) * i / nb; + // final Point2D cur = nullIfContained(points.getPoint(d), start, end); + // if (last != null && cur != null) { + // ug.draw(last.getX(), last.getY(), new ULine(cur.getX() - last.getX(), + // cur.getY() - last.getY())); + // if (decor != null) { + // decor.drawLine(ug, last, cur); + // decor = null; + // } + // } + // last = cur; + // } + // + // for (Point2D p : points.getPoints()) { + // ug.draw(p.getX() - 1, p.getY() - 1, new UEllipse(2, 2)); + // } + // } + +} diff --git a/src/net/sourceforge/plantuml/posimo/Positionable.java b/src/net/sourceforge/plantuml/posimo/Positionable.java new file mode 100644 index 000000000..e4c31bff4 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/Positionable.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; + +public interface Positionable { + + public Dimension2D getSize(); + + public Point2D getPosition(); + +} diff --git a/src/net/sourceforge/plantuml/posimo/PositionableUtils.java b/src/net/sourceforge/plantuml/posimo/PositionableUtils.java new file mode 100644 index 000000000..ad68afeb5 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/PositionableUtils.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.Dimension2DDouble; + +public class PositionableUtils { + + static public Rectangle2D convert(Positionable positionable) { + final Point2D position = positionable.getPosition(); + final Dimension2D size = positionable.getSize(); + return new Rectangle2D.Double(position.getX(), position.getY(), size.getWidth(), size.getHeight()); + } + + static public boolean contains(Positionable positionable, Point2D p) { + final Point2D position = positionable.getPosition(); + final Dimension2D size = positionable.getSize(); + final double width = size.getWidth(); + final double height = size.getHeight(); + + if (p.getX() < position.getX()) { + return false; + } + if (p.getX() > position.getX() + width) { + return false; + } + if (p.getY() < position.getY()) { + return false; + } + if (p.getY() > position.getY() + height) { + return false; + } + return true; + } + + static public Positionable addMargin(final Positionable pos, final double widthMargin, final double heightMargin) { + return new Positionable() { + + public Point2D getPosition() { + final Point2D p = pos.getPosition(); + return new Point2D.Double(p.getX() - widthMargin, p.getY() - heightMargin); + } + + public Dimension2D getSize() { + return Dimension2DDouble.delta(pos.getSize(), 2 * widthMargin, 2 * heightMargin); + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/posimo/SimpleDrawer.java b/src/net/sourceforge/plantuml/posimo/SimpleDrawer.java new file mode 100644 index 000000000..37adced8c --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/SimpleDrawer.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4236 $ + * + */ +package net.sourceforge.plantuml.posimo; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; + +public class SimpleDrawer { + + private final Cluster root; + private final Collection paths; + + public SimpleDrawer(Cluster root, Collection paths) { + this.root = root; + this.paths = paths; + } + + public void draw(Graphics2D g2d) { + g2d.setColor(Color.BLACK); + for (Clusterable cl : root.getContents()) { + final Block b = (Block) cl; + final Point2D pos = b.getPosition(); + final Dimension2D dim = b.getSize(); + // drawRectCentered(g2d, pos, dim); + drawRect(g2d, pos, dim); + } + + g2d.setColor(Color.GREEN); + for (Path p : paths) { + final Label label = p.getLabel(); + final Point2D labelPos = label.getPosition(); + final Dimension2D labelDim = label.getSize(); + // final double x1 = labelPos.getX(); + // final double y1 = labelPos.getY(); + // g2d.draw(new Ellipse2D.Double(x1 - 1, y1 - 1, 3, 3)); + // drawRectCentered(g2d, labelPos, labelDim); + drawRect(g2d, labelPos, labelDim); + } + + g2d.setColor(Color.RED); + for (Path p : paths) { + p.getDotPath().draw(g2d, 0, 0); + } + + for (Cluster sub : root.getSubClusters()) { + new SimpleDrawer(sub, new ArrayList()).draw(g2d); + } + + } + + private void drawRectCentered(Graphics2D g2d, final Point2D pos, final Dimension2D dim) { + final Rectangle2D rect = new Rectangle2D.Double(pos.getX() - dim.getWidth() / 2, pos.getY() - dim.getHeight() + / 2, dim.getWidth(), dim.getHeight()); + g2d.draw(rect); + } + + private void drawRect(Graphics2D g2d, final Point2D pos, final Dimension2D dim) { + final Rectangle2D rect = new Rectangle2D.Double(pos.getX(), pos.getY(), dim.getWidth(), dim.getHeight()); + g2d.draw(rect); + } +} diff --git a/src/net/sourceforge/plantuml/posimo/data.txt b/src/net/sourceforge/plantuml/posimo/data.txt new file mode 100644 index 000000000..2fe8aece5 --- /dev/null +++ b/src/net/sourceforge/plantuml/posimo/data.txt @@ -0,0 +1,38 @@ +@startuml +interface Positionable { + + Dimension2D getSize(); + + Point2D getPosition(); +} + +interface Clusterable { + +Cluster getParent(); +} + +Positionable <|-- Clusterable + +class Cluster + +Cluster *-- Cluster : subclusters +Clusterable <|.. Cluster +Cluster *-- Block +Clusterable <|.. Block + +Path *-- "2" Cluster +Path --> Label : has one +Positionable <|-- Label + +SimpleDrawer --> Cluster +SimpleDrawer *--> Path + +class GraphvizSolver { + + Dimension2D solve(Cluster root, Collection paths) +} +GraphvizSolver --> Cluster +GraphvizSolver *--> Path + + +'Clusterable --> Cluster : Parent + + + +@enduml diff --git a/src/net/sourceforge/plantuml/preproc/Defines.java b/src/net/sourceforge/plantuml/preproc/Defines.java new file mode 100644 index 000000000..75cec0509 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/Defines.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4154 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.util.Map; + +import net.sourceforge.plantuml.Pragma; + +public class Defines extends Pragma { + + public String applyDefines(String line) { + for (Map.Entry ent : this.entrySet()) { + final String key = ent.getKey(); + final String value = ent.getValue(); + if (value == null) { + continue; + } + final String regex = "\\b" + key + "\\b"; + line = line.replaceAll(regex, value); + } + return line; + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/IfManager.java b/src/net/sourceforge/plantuml/preproc/IfManager.java new file mode 100644 index 000000000..e124081e1 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/IfManager.java @@ -0,0 +1,101 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5200 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class IfManager implements ReadLine { + + protected static final Pattern ifdefPattern = Pattern.compile("^!if(n)?def\\s+([A-Za-z_][A-Za-z_0-9]*)$"); + protected static final Pattern elsePattern = Pattern.compile("^!else$"); + protected static final Pattern endifPattern = Pattern.compile("^!endif$"); + + private final Defines defines; + private final ReadLine source; + + private IfManager child; + + public IfManager(ReadLine source, Defines defines) { + this.defines = defines; + this.source = source; + } + + final public String readLine() throws IOException { + if (child != null) { + final String s = child.readLine(); + if (s != null) { + return s; + } + child = null; + } + + return readLineInternal(); + } + + protected String readLineInternal() throws IOException { + final String s = source.readLine(); + if (s == null) { + return null; + } + + final Matcher m = ifdefPattern.matcher(s); + if (m.find()) { + boolean ok = defines.isDefine(m.group(2)); + if (m.group(1) != null) { + ok = !ok; + } + if (ok) { + child = new IfManagerPositif(source, defines); + } else { + child = new IfManagerNegatif(source, defines); + } + // child = new IfManager(source, defines, ok ? IfPart.IF : + // IfPart.SKIP); + return this.readLine(); + } + + // m = endifPattern.matcher(s); + // if (m.find()) { + // return null; + // } + return s; + } + + public void close() throws IOException { + source.close(); + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java b/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java new file mode 100644 index 000000000..ddcdcb0ba --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.IOException; +import java.util.regex.Matcher; + +class IfManagerNegatif extends IfManager { + + private boolean skippingDone = false; + + public IfManagerNegatif(ReadLine source, Defines defines) { + super(source, defines); + } + + @Override + protected String readLineInternal() throws IOException { + if (skippingDone == false) { + skippingDone = true; + do { + final String s = readLine(); + if (s == null) { + return null; + } + Matcher m = endifPattern.matcher(s); + if (m.find()) { + return null; + } + m = elsePattern.matcher(s); + if (m.find()) { + break; + } + } while (true); + } + + final String s = super.readLineInternal(); + if (s == null) { + return null; + } + Matcher m = endifPattern.matcher(s); + if (m.find()) { + return null; + } + return s; + + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java b/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java new file mode 100644 index 000000000..113f94d50 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.IOException; +import java.util.regex.Matcher; + +class IfManagerPositif extends IfManager { + + public IfManagerPositif(ReadLine source, Defines defines) { + super(source, defines); + } + + @Override + protected String readLineInternal() throws IOException { + String s = super.readLineInternal(); + if (s == null) { + return null; + } + Matcher m = endifPattern.matcher(s); + if (m.find()) { + return null; + } + m = elsePattern.matcher(s); + if (m.find()) { + do { + s = readLine(); + if (s == null) { + return null; + } + m = endifPattern.matcher(s); + if (m.find()) { + return null; + } + } while (true); + } + return s; + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/Preprocessor.java b/src/net/sourceforge/plantuml/preproc/Preprocessor.java new file mode 100644 index 000000000..a0b7141e1 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/Preprocessor.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5200 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Preprocessor implements ReadLine { + + private static final Pattern definePattern = Pattern.compile("^!define\\s+([A-Za-z_][A-Za-z_0-9]*)(?:\\s+(.*))?$"); + private static final Pattern undefPattern = Pattern.compile("^!undef\\s+([A-Za-z_][A-Za-z_0-9]*)$"); + + private final Defines defines; + private final PreprocessorInclude rawSource; + private final IfManager source; + + public Preprocessor(ReadLine reader, Defines defines) { + this.defines = defines; + this.rawSource = new PreprocessorInclude(reader); + this.source = new IfManager(rawSource, defines); + } + + public String readLine() throws IOException { + String s = source.readLine(); + if (s == null) { + return null; + } + + Matcher m = definePattern.matcher(s); + if (m.find()) { + return manageDefine(m); + } + + m = undefPattern.matcher(s); + if (m.find()) { + return manageUndef(m); + } + + s = defines.applyDefines(s); + return s; + } + + private String manageUndef(Matcher m) throws IOException { + defines.undefine(m.group(1)); + return this.readLine(); + } + + private String manageDefine(Matcher m) throws IOException { + defines.define(m.group(1), m.group(2)); + return this.readLine(); + } + + public int getLineNumber() { + return rawSource.getLineNumber(); + } + + public void close() throws IOException { + rawSource.close(); + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java b/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java new file mode 100644 index 000000000..fdf341aa9 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java @@ -0,0 +1,100 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5207 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.FileSystem; + +class PreprocessorInclude implements ReadLine { + + private static final Pattern includePattern = Pattern.compile("^!include\\s+\"?([^\"]+)\"?$"); + + private final ReadLine reader2; + private int numLine = 0; + + private PreprocessorInclude included = null; + + public PreprocessorInclude(ReadLine reader) { + this.reader2 = reader; + } + + public String readLine() throws IOException { + if (included != null) { + final String s = included.readLine(); + if (s != null) { + return s; + } + included.close(); + included = null; + } + + final String s = reader2.readLine(); + numLine++; + if (s == null) { + return null; + } + final Matcher m = includePattern.matcher(s); + assert included == null; + if (m.find()) { + return manageInclude(m); + } + + return s; + + } + + private String manageInclude(Matcher m) throws IOException, FileNotFoundException { + final String fileName = m.group(1); + final File f = FileSystem.getInstance().getFile(fileName); + if (f.exists()) { + included = new PreprocessorInclude(new ReadLineReader(new FileReader(f))); + } + return this.readLine(); + } + + public int getLineNumber() { + return numLine; + } + + public void close() throws IOException { + reader2.close(); + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/ReadLine.java b/src/net/sourceforge/plantuml/preproc/ReadLine.java new file mode 100644 index 000000000..a02e2f31f --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/ReadLine.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5200 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.Closeable; +import java.io.IOException; + +interface ReadLine extends Closeable { + + public String readLine() throws IOException; +} diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java new file mode 100644 index 000000000..3824f2c6f --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; + +public class ReadLineReader implements ReadLine { + + private final BufferedReader br; + + public ReadLineReader(Reader reader) { + br = new BufferedReader(reader); + } + + public String readLine() throws IOException { + String s = br.readLine(); + if (s != null && s.startsWith("\uFEFF")) { + s = s.substring(1); + } + return s; + } + + public void close() throws IOException { + br.close(); + } + +} diff --git a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java new file mode 100644 index 000000000..89c23d6a4 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5200 $ + * + */ +package net.sourceforge.plantuml.preproc; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class UncommentReadLine implements ReadLine { + + private final ReadLine raw; + private final Pattern start; + private String headerToRemove; + + public UncommentReadLine(ReadLine source) { + this.raw = source; + this.start = Pattern.compile("(?i)(\\W*)@startuml"); + } + + public String readLine() throws IOException { + String s = readLine2(); + if (s != null) { + s = cleanLineFromSource(s); + } + return s; + } + + public static String cleanLineFromSource(String s) { + s = s.trim(); + while (s.startsWith(" ") || s.startsWith("\t")) { + s = s.substring(1).trim(); + } + return s; + } + + private String readLine2() throws IOException { + final String result = raw.readLine(); + + if (result == null) { + return null; + } + + final Matcher m = start.matcher(result); + if (m.find()) { + headerToRemove = m.group(1); + } + if (headerToRemove != null && headerToRemove.startsWith(result)) { + return ""; + } + if (headerToRemove != null && result.startsWith(headerToRemove)) { + return result.substring(headerToRemove.length()); + } + return result; + } + + public void close() throws IOException { + this.raw.close(); + } + +} diff --git a/src/net/sourceforge/plantuml/printskin/PrintSkin.java b/src/net/sourceforge/plantuml/printskin/PrintSkin.java new file mode 100644 index 000000000..49065aabb --- /dev/null +++ b/src/net/sourceforge/plantuml/printskin/PrintSkin.java @@ -0,0 +1,160 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4633 $ + * + */ +package net.sourceforge.plantuml.printskin; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.SkinParam; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.skin.SkinUtils; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; + +class PrintSkin extends AbstractPSystem { + + private static final Font FONT1 = new Font("SansSerif", Font.PLAIN, 10); + + final private Skin skin; + final private List toPrint; + private UGraphic ug; + private float xpos = 10; + private float ypos = 0; + private float maxYpos = 0; + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + final List result = Arrays.asList(suggestedFile); + final BufferedImage im = createImage(); + + PngIO.write(im.getSubimage(0, 0, im.getWidth(), (int) maxYpos), suggestedFile); + return result; + + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + final BufferedImage im = createImage(); + PngIO.write(im.getSubimage(0, 0, im.getWidth(), (int) maxYpos), os); + } + + private BufferedImage createImage() { + final EmptyImageBuilder builder = new EmptyImageBuilder(1000, 1000, Color.WHITE); + + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + ug = new UGraphicG2d(g2d, null); + + for (ComponentType type : EnumSet.allOf(ComponentType.class)) { + printComponent(type); + ypos += 10; + maxYpos = Math.max(maxYpos, ypos); + if (ypos > 500) { + ypos = 0; + xpos += 200; + } + } + g2d.dispose(); + return im; + } + + private void printComponent(ComponentType type) { + println(type.name()); + final Component comp = skin.createComponent(type, new SkinParam(), toPrint); + if (comp == null) { + println("null"); + return; + } + double height = comp.getPreferredHeight(ug.getStringBounder()); + double width = comp.getPreferredWidth(ug.getStringBounder()); + println("height = " + String.format("%4.2f", height)); + println("width = " + width); + + if (height == 0) { + height = 42; + } + if (width == 0) { + width = 42; + } + ug.getParam().setColor(Color.LIGHT_GRAY); + ug.getParam().setBackcolor(Color.LIGHT_GRAY); + ug.draw(xpos-1, ypos-1, new URectangle(width+2, height+2)); + //g2d.drawRect((int) xpos - 1, (int) ypos - 1, (int) width + 2, (int) height + 2); + + //final AffineTransform at = g2d.getTransform(); + //g2d.translate(xpos, ypos); + ug.translate(xpos, ypos); + ug.getParam().reset(); + comp.drawU(ug, new Dimension2DDouble(width, height), new SimpleContext2D(false)); + ug.translate(-xpos, -ypos); + //g2d.setTransform(at); + + ypos += height; + } + + private void println(String s) { + final TextBlock textBlock = TextBlockUtils.create(Arrays.asList(s), FONT1, Color.BLACK, + HorizontalAlignement.LEFT); + textBlock.drawU(ug, xpos, ypos); + ypos += textBlock.calculateDimension(ug.getStringBounder()).getHeight(); + } + + public String getDescription() { + return "Printing of " + skin.getClass().getName(); + } + + public PrintSkin(String className, List toPrint) { + this.skin = SkinUtils.loadSkin(className); + this.toPrint = toPrint; + } +} diff --git a/src/net/sourceforge/plantuml/printskin/PrintSkinFactory.java b/src/net/sourceforge/plantuml/printskin/PrintSkinFactory.java new file mode 100644 index 000000000..3fc8c387c --- /dev/null +++ b/src/net/sourceforge/plantuml/printskin/PrintSkinFactory.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.printskin; + +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PrintSkinFactory implements PSystemBasicFactory { + + private PrintSkin system; + + // private List cmds; + + public PrintSkinFactory() { + reset(); + } + + public void reset() { + } + + public PrintSkin getSystem() { + return system; + } + + static final Pattern p = Pattern.compile("(?i)^testskin\\s+([\\w.]+)\\s*(.*)$"); + + public boolean executeLine(String line) { + final Matcher m = p.matcher(line); + if (m.find() == false) { + return false; + } + system = new PrintSkin(m.group(1), Arrays.asList(m.group(2))); + return true; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java new file mode 100644 index 000000000..f2523dd79 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java @@ -0,0 +1,123 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public abstract class AbstractMessage implements Event { + + final private List label; + final private boolean dotted; + final private boolean full; + final private List lifeEvents = new ArrayList(); + + private List notes; + private NotePosition notePosition; + private HtmlColor noteBackColor; + private final String messageNumber; + + public AbstractMessage(List label, boolean dotted, boolean full, String messageNumber) { + this.label = label; + this.dotted = dotted; + this.full = full; + this.messageNumber = messageNumber; + } + + public final void addLifeEvent(LifeEvent lifeEvent) { + this.lifeEvents.add(lifeEvent); + } + + public final boolean isCreate() { + for (LifeEvent le : lifeEvents) { + if (le.getType() == LifeEventType.CREATE) { + return true; + } + } + return false; + } + + public final boolean isActivateAndDeactive() { + if (lifeEvents.size() < 2) { + return false; + } + return lifeEvents.get(0).getType() == LifeEventType.ACTIVATE + && (lifeEvents.get(1).getType() == LifeEventType.DEACTIVATE || lifeEvents.get(1).getType() == LifeEventType.DESTROY); + } + + public final List getLiveEvents() { + return Collections.unmodifiableList(lifeEvents); + } + + public final List getLabel() { + return Collections.unmodifiableList(label); + } + + public final boolean isDotted() { + return dotted; + } + + public final boolean isFull() { + return full; + } + + public final List getNote() { + return notes == null ? notes : Collections.unmodifiableList(notes); + } + + public final void setNote(List strings, NotePosition notePosition, String backcolor) { + if (notePosition != NotePosition.LEFT && notePosition != NotePosition.RIGHT) { + throw new IllegalArgumentException(); + } + this.notes = strings; + this.notePosition = notePosition; + this.noteBackColor = HtmlColor.getColorIfValid(backcolor); + } + + public final HtmlColor getSpecificBackColor() { + return noteBackColor; + } + + public final NotePosition getNotePosition() { + return notePosition; + } + + public final String getMessageNumber() { + return messageNumber; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Divider.java b/src/net/sourceforge/plantuml/sequencediagram/Divider.java new file mode 100644 index 000000000..6595899d1 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Divider.java @@ -0,0 +1,50 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.List; + +public class Divider implements Event { + + private final List text; + + public Divider(List text) { + this.text = text; + } + + public final List getText() { + return text; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Event.java b/src/net/sourceforge/plantuml/sequencediagram/Event.java new file mode 100644 index 000000000..1880fce0e --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Event.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public interface Event { + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Grouping.java b/src/net/sourceforge/plantuml/sequencediagram/Grouping.java new file mode 100644 index 000000000..c9f4ef49f --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Grouping.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4320 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public abstract class Grouping implements Event { + + private final String title; + private final GroupingType type; + private final String comment; + private final HtmlColor backColorElement; + + public Grouping(String title, String comment, GroupingType type, + HtmlColor backColorElement) { + this.title = title; + this.comment = comment; + this.type = type; + this.backColorElement = backColorElement; + } + + @Override + public final String toString() { + return super.toString() + " " + type + " " + title; + } + + final public String getTitle() { + return title; + } + + final public GroupingType getType() { + return type; + } + + public abstract int getLevel(); + + public abstract HtmlColor getBackColorGeneral(); + + final public String getComment() { + return comment; + } + + public final HtmlColor getBackColorElement() { + return backColorElement; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/GroupingLeaf.java b/src/net/sourceforge/plantuml/sequencediagram/GroupingLeaf.java new file mode 100644 index 000000000..0cd8171d4 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/GroupingLeaf.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4321 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class GroupingLeaf extends Grouping { + + private final GroupingStart start; + private final HtmlColor backColorGeneral; + + public GroupingLeaf(String title, String comment, GroupingType type, HtmlColor backColorGeneral, + HtmlColor backColorElement, GroupingStart start) { + super(title, comment, type, backColorElement); + if (start == null) { + throw new IllegalArgumentException(); + } + this.backColorGeneral = backColorGeneral; + this.start = start; + start.addChildren(this); + } + + public Grouping getJustBefore() { + final int idx = start.getChildren().indexOf(this); + if (idx == -1) { + throw new IllegalStateException(); + } + if (idx == 0) { + return start; + } + return start.getChildren().get(idx - 1); + } + + @Override + public int getLevel() { + return start.getLevel(); + } + + @Override + public final HtmlColor getBackColorGeneral() { + if (backColorGeneral == null) { + return start.getBackColorGeneral(); + } + return backColorGeneral; + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/GroupingStart.java b/src/net/sourceforge/plantuml/sequencediagram/GroupingStart.java new file mode 100644 index 000000000..049f3ca74 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/GroupingStart.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4282 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class GroupingStart extends Grouping { + + private final List children = new ArrayList(); + private final HtmlColor backColorGeneral; + + final private GroupingStart parent; + + public GroupingStart(String title, String comment, HtmlColor backColorGeneral, HtmlColor backColorElement, + GroupingStart parent) { + super(title, comment, GroupingType.START, backColorElement); + this.backColorGeneral = backColorGeneral; + this.parent = parent; + } + + List getChildren() { + return Collections.unmodifiableList(children); + } + + public void addChildren(GroupingLeaf g) { + children.add(g); + } + + public int getLevel() { + if (parent == null) { + return 0; + } + return parent.getLevel() + 1; + } + + @Override + public HtmlColor getBackColorGeneral() { + return backColorGeneral; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/GroupingType.java b/src/net/sourceforge/plantuml/sequencediagram/GroupingType.java new file mode 100644 index 000000000..bf2ff6c91 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/GroupingType.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5523 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public enum GroupingType { + START, ELSE, END; + public static GroupingType getType(String s) { + if (s.equalsIgnoreCase("opt")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("alt")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("loop")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("par")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("break")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("group")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("critical")) { + return GroupingType.START; + } else if (s.equalsIgnoreCase("else")) { + return GroupingType.ELSE; + } else if (s.equalsIgnoreCase("end")) { + return GroupingType.END; + } + + throw new IllegalArgumentException(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java b/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java new file mode 100644 index 000000000..84ea61791 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4259 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public interface InGroupable { + + public double getMinX(StringBounder stringBounder); + + public double getMaxX(StringBounder stringBounder); + + public String toString(StringBounder stringBounder); + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java b/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java new file mode 100644 index 000000000..69f21c168 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java @@ -0,0 +1,175 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4259 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.HashSet; +import java.util.Set; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.graphic.LivingParticipantBox; +import net.sourceforge.plantuml.sequencediagram.graphic.ParticipantBox; +import net.sourceforge.plantuml.sequencediagram.graphic.VirtualHBar; +import net.sourceforge.plantuml.sequencediagram.graphic.VirtualHBarType; + +public class InGroupableList implements InGroupable { + + //public static boolean NEW_METHOD = true; + + private final GroupingStart groupingStart; + private final Set inGroupables = new HashSet(); + private final VirtualHBar barStart; + private final VirtualHBar barEnd; + + private double minWidth; + + public InGroupableList(GroupingStart groupingStart, double startingY) { + this.groupingStart = groupingStart; + this.barStart = new VirtualHBar(10, VirtualHBarType.START, startingY); + this.barEnd = new VirtualHBar(10, VirtualHBarType.END, startingY); + } + + public final void setEndingY(double endingY) { + this.barStart.setEndingY(endingY); + this.barEnd.setEndingY(endingY); + } + + public void addInGroupable(InGroupable in) { + this.inGroupables.add(in); + } + + public boolean isEmpty() { + return inGroupables.isEmpty(); + } + + @Override + public String toString() { + return "GS " + groupingStart + " " + inGroupables.toString(); + } + + public String toString(StringBounder stringBounder) { + final StringBuilder sb = new StringBuilder("GS " + groupingStart + " "); + for (InGroupable in : inGroupables) { + sb.append(in.toString(stringBounder)); + sb.append(' '); + } + return sb.toString(); + } + + public double getMinX(StringBounder stringBounder) { + if (inGroupables.size() == 0) { + return 0; + } + double result = Double.MAX_VALUE; + for (InGroupable in : inGroupables) { + final double v = in.getMinX(stringBounder); + if (v < result) { + result = v; + } + } + return result; + } + + public double getMaxX(StringBounder stringBounder) { + if (inGroupables.size() == 0) { + return minWidth; + } + double result = 0; + for (InGroupable in : inGroupables) { + final double v = in.getMaxX(stringBounder); + if (v > result) { + result = v; + } + } + final double minX = getMinX(stringBounder); + if (result < minX + minWidth) { + return minX + minWidth; + } + return result; + } + + public void setMinWidth(double minWidth) { + this.minWidth = minWidth; + } + + public ParticipantBox getFirstParticipantBox() { + ParticipantBox first = null; + for (InGroupable in : inGroupables) { + if (in instanceof LivingParticipantBox) { + final ParticipantBox participantBox = ((LivingParticipantBox) in).getParticipantBox(); + if (first == null || participantBox.getStartingX() < first.getStartingX()) { + first = participantBox; + } + } + } + return first; + } + + public ParticipantBox getLastParticipantBox() { + ParticipantBox last = null; + for (InGroupable in : inGroupables) { + if (in instanceof LivingParticipantBox) { + final ParticipantBox participantBox = ((LivingParticipantBox) in).getParticipantBox(); + if (last == null || participantBox.getStartingX() > last.getStartingX()) { + last = participantBox; + } + } + } + return last; + } + + // public void pushAllToLeft(double delta) { + // for (InGroupable in : inGroupables) { + // System.err.println("in=" + in); + // if (in instanceof LivingParticipantBox) { + // final ParticipantBox participantBox = ((LivingParticipantBox) + // in).getParticipantBox(); + // System.err.println("PUSHING " + participantBox + " " + delta); + // participantBox.pushToLeft(delta); + // } + // } + // } + // + // public final double getBarStartX(StringBounder stringBounder) { + // return getMinX(stringBounder) - barStart.getWidth() / 2; + // } + + public final VirtualHBar getBarStart() { + return barStart; + } + + public final VirtualHBar getBarEnd() { + return barEnd; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/LifeEvent.java b/src/net/sourceforge/plantuml/sequencediagram/LifeEvent.java new file mode 100644 index 000000000..987f16a6e --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/LifeEvent.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4243 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class LifeEvent implements Event { + + private final Participant p; + private final LifeEventType type; + private final HtmlColor backcolor; + + public LifeEvent(Participant p, LifeEventType type, HtmlColor backcolor) { + this.p = p; + this.type = type; + this.backcolor = backcolor; + } + + public Participant getParticipant() { + return p; + } + + public LifeEventType getType() { + return type; + } + + public HtmlColor getSpecificBackColor() { + return backcolor; + } + + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/LifeEventType.java b/src/net/sourceforge/plantuml/sequencediagram/LifeEventType.java new file mode 100644 index 000000000..fdf60aa1e --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/LifeEventType.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public enum LifeEventType { + ACTIVATE, DEACTIVATE, DESTROY, CREATE + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Message.java b/src/net/sourceforge/plantuml/sequencediagram/Message.java new file mode 100644 index 000000000..b3d150c06 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Message.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4663 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.List; + +public class Message extends AbstractMessage { + + final private Participant p1; + final private Participant p2; + + public Message(Participant p1, Participant p2, List label, + boolean dotted, boolean full, String messageNumber) { + super(label, dotted, full, messageNumber); + this.p1 = p1; + this.p2 = p2; + } + + public Participant getParticipant1() { + return p1; + } + + public Participant getParticipant2() { + return p2; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java new file mode 100644 index 000000000..10d9f14eb --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.List; + +public class MessageExo extends AbstractMessage { + + final private MessageExoType type; + final private Participant participant; + + public MessageExo(Participant p, MessageExoType type, List label, + boolean dotted, boolean full, String messageNumber) { + super(label, dotted, full, messageNumber); + this.participant = p; + this.type = type; + } + + public Participant getParticipant() { + return participant; + } + + public final MessageExoType getType() { + return type; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java b/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java new file mode 100644 index 000000000..262f9264f --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public enum MessageExoType { + FROM_LEFT, TO_LEFT, FROM_RIGHT, TO_RIGHT; + + public int getDirection() { + if (this == MessageExoType.FROM_LEFT) { + return 1; + } + if (this == MessageExoType.TO_LEFT) { + return -1; + } + if (this == MessageExoType.TO_RIGHT) { + return 1; + } + if (this == MessageExoType.FROM_RIGHT) { + return -1; + } + throw new IllegalStateException(); + } + + public boolean isLeftBorder() { + return this == MessageExoType.FROM_LEFT || this == MessageExoType.TO_LEFT; + } + + public boolean isRightBorder() { + return this == MessageExoType.FROM_RIGHT || this == MessageExoType.TO_RIGHT; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/MessageNumber.java b/src/net/sourceforge/plantuml/sequencediagram/MessageNumber.java new file mode 100644 index 000000000..e71c98862 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/MessageNumber.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public class MessageNumber implements CharSequence { + + private final String representation; + + @Override + public String toString() { + return representation; + } + + public MessageNumber(String s) { + this.representation = s; + } + + public String getNumber() { + return representation; + } + + public char charAt(int arg0) { + return representation.charAt(arg0); + } + + public int length() { + return representation.length(); + } + + public CharSequence subSequence(int arg0, int arg1) { + return representation.subSequence(arg0, arg1); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Newpage.java b/src/net/sourceforge/plantuml/sequencediagram/Newpage.java new file mode 100644 index 000000000..12544faaa --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Newpage.java @@ -0,0 +1,50 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.List; + +public class Newpage implements Event { + + private final List title; + + public Newpage(List strings) { + this.title = strings; + } + + public final List getTitle() { + return title; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Note.java b/src/net/sourceforge/plantuml/sequencediagram/Note.java new file mode 100644 index 000000000..6132a9924 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Note.java @@ -0,0 +1,90 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4237 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.List; + +import net.sourceforge.plantuml.SpecificBackcolorable; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class Note implements Event, SpecificBackcolorable { + + private final Participant p; + private final Participant p2; + + private final List strings; + + private final NotePosition position; + + public Note(Participant p, NotePosition position, List strings) { + this.p = p; + this.p2 = null; + this.position = position; + this.strings = strings; + } + + public Note(Participant p, Participant p2, List strings) { + this.p = p; + this.p2 = p2; + this.position = NotePosition.OVER_SEVERAL; + this.strings = strings; + } + + public Participant getParticipant() { + return p; + } + + public Participant getParticipant2() { + return p2; + } + + public List getStrings() { + return strings; + } + + public NotePosition getPosition() { + return position; + } + + private HtmlColor specificBackcolor; + + public HtmlColor getSpecificBackColor() { + return specificBackcolor; + } + + public void setSpecificBackcolor(String s) { + this.specificBackcolor = HtmlColor.getColorIfValid(s); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/NotePosition.java b/src/net/sourceforge/plantuml/sequencediagram/NotePosition.java new file mode 100644 index 000000000..5a31d379f --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/NotePosition.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public enum NotePosition { + LEFT, RIGHT, OVER, OVER_SEVERAL +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/Participant.java b/src/net/sourceforge/plantuml/sequencediagram/Participant.java new file mode 100644 index 000000000..5d16106c3 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Participant.java @@ -0,0 +1,120 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.SpecificBackcolorable; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class Participant implements SpecificBackcolorable { + + private final String code; + private final List display; + private final ParticipantType type; + + private int initialLife = 0; + + private Stereotype stereotype; + + public Participant(ParticipantType type, String code, List display) { + if (type == null) { + throw new IllegalArgumentException(); + } + if (code == null || code.length() == 0) { + throw new IllegalArgumentException(); + } + if (display == null || display.size() == 0) { + throw new IllegalArgumentException(); + } + this.code = code; + this.type = type; + this.display = new ArrayList(display); + } + + public String getCode() { + return code; + } + + public List getDisplay() { + return Collections.unmodifiableList(display); + } + + public ParticipantType getType() { + return type; + } + + public final void setStereotype(Stereotype stereotype) { + if (type == ParticipantType.ACTOR) { + return; + } + if (this.stereotype != null) { + throw new IllegalStateException(); + } + if (stereotype == null) { + throw new IllegalArgumentException(); + } + this.stereotype = stereotype; + display.add(0, stereotype); + } + + public final int getInitialLife() { + return initialLife; + } + + private HtmlColor liveBackcolor; + + public final void incInitialLife(HtmlColor backcolor) { + initialLife++; + this.liveBackcolor = backcolor; + } + + public HtmlColor getLiveSpecificBackColor() { + return liveBackcolor; + } + + private HtmlColor specificBackcolor; + + public HtmlColor getSpecificBackColor() { + return specificBackcolor; + } + + public void setSpecificBackcolor(String s) { + this.specificBackcolor = HtmlColor.getColorIfValid(s); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/ParticipantEnglober.java b/src/net/sourceforge/plantuml/sequencediagram/ParticipantEnglober.java new file mode 100644 index 000000000..841f9b124 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/ParticipantEnglober.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.List; + +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class ParticipantEnglober { + + final private List title; + final private Participant first; + final private Participant last; + final private HtmlColor boxColor; + + public ParticipantEnglober(Participant first, Participant last, List title, HtmlColor boxColor) { + if (first == null || last == null) { + throw new IllegalArgumentException(); + } + this.first = first; + this.last = last; + this.title = title; + this.boxColor = boxColor; + } + + public final Participant getFirst() { + return first; + } + + public final Participant getLast() { + return last; + } + + public final List getTitle() { + return title; + } + + public final HtmlColor getBoxColor() { + return boxColor; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/ParticipantType.java b/src/net/sourceforge/plantuml/sequencediagram/ParticipantType.java new file mode 100644 index 000000000..9ded618c4 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/ParticipantType.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +public enum ParticipantType { + PARTICIPANT, ACTOR + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java new file mode 100644 index 000000000..73601393a --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -0,0 +1,323 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.UmlDiagram; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.sequencediagram.graphic.FileMaker; +import net.sourceforge.plantuml.sequencediagram.graphic.SequenceDiagramFileMaker; +import net.sourceforge.plantuml.sequencediagram.graphic.SequenceDiagramTxtMaker; +import net.sourceforge.plantuml.skin.ProtectedSkin; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.skin.SkinUtils; +import net.sourceforge.plantuml.skin.rose.Rose; + +public class SequenceDiagram extends UmlDiagram { + + private final Map participants = new LinkedHashMap(); + + private final List events = new ArrayList(); + + private final List participantEnglobers = new ArrayList(); + + private Skin skin = new ProtectedSkin(new Rose()); + + public Participant getOrCreateParticipant(String code) { + Participant result = participants.get(code); + if (result == null) { + result = new Participant(ParticipantType.PARTICIPANT, code, Arrays.asList(code)); + participants.put(code, result); + } + return result; + } + + private AbstractMessage lastMessage; + + public AbstractMessage getLastMessage() { + return lastMessage; + } + + public Participant createNewParticipant(ParticipantType type, String code, List display) { + if (participants.containsKey(code)) { + throw new IllegalArgumentException(); + } + if (display == null) { + display = Arrays.asList(code); + } + final Participant result = new Participant(type, code, display); + participants.put(code, result); + return result; + } + + public Map participants() { + return Collections.unmodifiableMap(participants); + } + + public void addMessage(AbstractMessage m) { + lastMessage = m; + events.add(m); + if (pendingCreate != null) { + m.addLifeEvent(pendingCreate); + pendingCreate = null; + } + } + + public void addNote(Note n) { + events.add(n); + } + + public void newpage(List strings) { + if (ignoreNewpage) { + return; + } + events.add(new Newpage(strings)); + } + + private boolean ignoreNewpage = false; + + public void ignoreNewpage() { + this.ignoreNewpage = true; + } + + private int autonewpage = -1; + + public final int getAutonewpage() { + return autonewpage; + } + + public void setAutonewpage(int autonewpage) { + this.autonewpage = autonewpage; + } + + public void divider(List strings) { + events.add(new Divider(strings)); + } + + public List events() { + return Collections.unmodifiableList(events); + } + + private FileMaker getSequenceDiagramPngMaker(FileFormat fileFormat) { + + if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { + return new SequenceDiagramTxtMaker(this, fileFormat); + } + + return new SequenceDiagramFileMaker(this, skin, fileFormat); + // if (fileFormat == FileFormat.TXT) { + // return new SequenceDiagramPngMaker(this, new TextSkin()); + // } else if (OptionFlags.getInstance().useU()) { + // return new SequenceDiagramFileMaker(this, skin, fileFormat); + // } + // return new SequenceDiagramPngMaker(this, skin); + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException { + return getSequenceDiagramPngMaker(fileFormat).createMany(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getSequenceDiagramPngMaker(fileFormat).createOne(os, index); + } + + private LifeEvent pendingCreate = null; + + public void activate(Participant p, LifeEventType lifeEventType, HtmlColor backcolor) { + if (lifeEventType == LifeEventType.CREATE) { + pendingCreate = new LifeEvent(p, lifeEventType, backcolor); + return; + } + if (lastMessage == null) { + if (lifeEventType == LifeEventType.ACTIVATE) { + p.incInitialLife(backcolor); + } + return; + // throw new + // UnsupportedOperationException("Step1Message::beforeMessage"); + } + lastMessage.addLifeEvent(new LifeEvent(p, lifeEventType, backcolor)); + } + + private final List openGroupings = new ArrayList(); + + public boolean grouping(String title, String comment, GroupingType type, HtmlColor backColorGeneral, + HtmlColor backColorElement) { + if (type != GroupingType.START && openGroupings.size() == 0) { + return false; + } + + final GroupingStart top = openGroupings.size() > 0 ? openGroupings.get(0) : null; + + final Grouping g = type == GroupingType.START ? new GroupingStart(title, comment, backColorGeneral, + backColorElement, top) + : new GroupingLeaf(title, comment, type, backColorGeneral, backColorElement, top); + events.add(g); + + if (type == GroupingType.START) { + openGroupings.add(0, (GroupingStart) g); + } else if (type == GroupingType.END) { + openGroupings.remove(0); + } + + return true; + } + + public String getDescription() { + return "(" + participants.size() + " participants)"; + } + + public boolean changeSkin(String className) { + final Skin s = SkinUtils.loadSkin(className); + final Integer expected = new Integer(1); + if (s != null && expected.equals(s.getProtocolVersion())) { + this.skin = new ProtectedSkin(s); + return true; + } + return false; + } + + public Skin getSkin() { + return skin; + } + + private Integer messageNumber = null; + private int incrementMessageNumber; + + private DecimalFormat decimalFormat; + + public final void goAutonumber(int startingNumber, int increment, DecimalFormat decimalFormat) { + this.messageNumber = startingNumber; + this.incrementMessageNumber = increment; + this.decimalFormat = decimalFormat; + } + + public String getNextMessageNumber() { + if (messageNumber == null) { + return null; + } + final Integer result = messageNumber; + messageNumber += incrementMessageNumber; + return decimalFormat.format(result); + } + + public boolean isShowFootbox() { + return showFootbox; + } + + private boolean showFootbox = true; + + public void setShowFootbox(boolean footbox) { + this.showFootbox = footbox; + + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.SEQUENCE; + } + + private Participant boxStart; + private List boxStartComment; + private HtmlColor boxColor; + private boolean boxPending = false; + + public void boxStart(List comment, HtmlColor color) { + if (boxPending) { + throw new IllegalStateException(); + } + this.boxStart = getLastParticipant(); + this.boxStartComment = comment; + this.boxColor = color; + this.boxPending = true; + } + + public void endBox() { + if (boxPending == false) { + throw new IllegalStateException(); + } + final Participant last = getLastParticipant(); + this.participantEnglobers.add(new ParticipantEnglober(next(boxStart), last, boxStartComment, boxColor)); + this.boxStart = null; + this.boxStartComment = null; + this.boxColor = null; + this.boxPending = false; + } + + public boolean isBoxPending() { + return boxPending; + } + + private Participant next(Participant p) { + if (p == null) { + return participants.values().iterator().next(); + } + for (final Iterator it = participants.values().iterator(); it.hasNext();) { + final Participant current = it.next(); + if (current == p && it.hasNext()) { + return it.next(); + } + } + throw new IllegalArgumentException("p=" + p.getCode()); + } + + private Participant getLastParticipant() { + Participant result = null; + for (Participant p : participants.values()) { + result = p; + } + return result; + } + + public final List getParticipantEnglobers() { + return Collections.unmodifiableList(participantEnglobers); + } + + @Override + public int getNbImages() { + return getSequenceDiagramPngMaker(FileFormat.PNG).getNbPages(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java new file mode 100644 index 000000000..f1b6a8cd8 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java @@ -0,0 +1,108 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5397 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.sequencediagram.command.CommandActivate; +import net.sourceforge.plantuml.sequencediagram.command.CommandActivate2; +import net.sourceforge.plantuml.sequencediagram.command.CommandArrow; +import net.sourceforge.plantuml.sequencediagram.command.CommandAutoNewpage; +import net.sourceforge.plantuml.sequencediagram.command.CommandAutonumber; +import net.sourceforge.plantuml.sequencediagram.command.CommandBoxEnd; +import net.sourceforge.plantuml.sequencediagram.command.CommandBoxStart; +import net.sourceforge.plantuml.sequencediagram.command.CommandDivider; +import net.sourceforge.plantuml.sequencediagram.command.CommandExoArrowLeft; +import net.sourceforge.plantuml.sequencediagram.command.CommandExoArrowRight; +import net.sourceforge.plantuml.sequencediagram.command.CommandFootbox; +import net.sourceforge.plantuml.sequencediagram.command.CommandFootboxOld; +import net.sourceforge.plantuml.sequencediagram.command.CommandGrouping; +import net.sourceforge.plantuml.sequencediagram.command.CommandIgnoreNewpage; +import net.sourceforge.plantuml.sequencediagram.command.CommandMultilinesNote; +import net.sourceforge.plantuml.sequencediagram.command.CommandMultilinesNoteOnArrow; +import net.sourceforge.plantuml.sequencediagram.command.CommandMultilinesNoteOverSeveral; +import net.sourceforge.plantuml.sequencediagram.command.CommandNewpage; +import net.sourceforge.plantuml.sequencediagram.command.CommandNoteOnArrow; +import net.sourceforge.plantuml.sequencediagram.command.CommandNoteOverSeveral; +import net.sourceforge.plantuml.sequencediagram.command.CommandNoteSequence; +import net.sourceforge.plantuml.sequencediagram.command.CommandParticipant; +import net.sourceforge.plantuml.sequencediagram.command.CommandParticipant2; +import net.sourceforge.plantuml.sequencediagram.command.CommandSkin; + +public class SequenceDiagramFactory extends AbstractUmlSystemCommandFactory { + + private SequenceDiagram system; + + @Override + protected void initCommands() { + system = new SequenceDiagram(); + + addCommonCommands(system); + + addCommand(new CommandParticipant(system)); + addCommand(new CommandParticipant2(system)); + addCommand(new CommandArrow(system)); + addCommand(new CommandExoArrowLeft(system)); + addCommand(new CommandExoArrowRight(system)); + addCommand(new CommandNoteSequence(system)); + addCommand(new CommandNoteOverSeveral(system)); + + addCommand(new CommandBoxStart(system)); + addCommand(new CommandBoxEnd(system)); + addCommand(new CommandGrouping(system)); + + addCommand(new CommandActivate(system)); + addCommand(new CommandActivate2(system)); + + addCommand(new CommandNoteOnArrow(system)); + + addCommand(new CommandMultilinesNote(system)); + addCommand(new CommandMultilinesNoteOverSeveral(system)); + addCommand(new CommandMultilinesNoteOnArrow(system)); + + addCommand(new CommandNewpage(system)); + addCommand(new CommandIgnoreNewpage(system)); + addCommand(new CommandAutoNewpage(system)); + addCommand(new CommandDivider(system)); + addCommand(new CommandSkin(system)); + addCommand(new CommandAutonumber(system)); + addCommand(new CommandFootbox(system)); + addCommand(new CommandFootboxOld(system)); + + } + + public SequenceDiagram getSystem() { + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java new file mode 100644 index 000000000..247585c9e --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.sequencediagram.LifeEventType; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandActivate extends SingleLineCommand { + + public CommandActivate(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^(activate|deactivate|destroy|create)\\s+([\\p{L}0-9_.]+)\\s*(#\\w+)?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final LifeEventType type = LifeEventType.valueOf(arg.get(0).toUpperCase()); + final Participant p = getSystem().getOrCreateParticipant(arg.get(1)); + getSystem().activate(p, type, HtmlColor.getColorIfValid(arg.get(2))); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate2.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate2.java new file mode 100644 index 000000000..23a6bac36 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate2.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.sequencediagram.LifeEventType; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandActivate2 extends SingleLineCommand { + + public CommandActivate2(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^([\\p{L}0-9_.]+)\\s*(\\+\\+|--)\\s*(#\\w+)?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final LifeEventType type = arg.get(1).equals("++") ? LifeEventType.ACTIVATE : LifeEventType.DEACTIVATE; + final Participant p = getSystem().getOrCreateParticipant(arg.get(0)); + getSystem().activate(p, type, HtmlColor.getColorIfValid(arg.get(2))); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java new file mode 100644 index 000000000..097067d7a --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5424 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandArrow extends SingleLineCommand { + + public CommandArrow(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, + "(?i)^([\\p{L}0-9_.]+)\\s*([=-]+[>\\]]{1,2}|[<\\[]{1,2}[=-]+)\\s*([\\p{L}0-9_.]+)\\s*(?::\\s*(.*))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + Participant p1; + Participant p2; + + final String arrow = StringUtils.manageArrowForSequence(arg.get(1)); + + if (arrow.endsWith(">")) { + p1 = getSystem().getOrCreateParticipant(arg.get(0)); + p2 = getSystem().getOrCreateParticipant(arg.get(2)); + } else if (arrow.startsWith("<")) { + p2 = getSystem().getOrCreateParticipant(arg.get(0)); + p1 = getSystem().getOrCreateParticipant(arg.get(2)); + } else { + throw new IllegalStateException(arg.toString()); + } + + final boolean full = (arrow.endsWith(">>") || arrow.startsWith("<<"))==false; + + final boolean dotted = arrow.contains("--"); + + final List labels; + if (arg.get(3) == null) { + labels = Arrays.asList(""); + } else { + labels = StringUtils.getWithNewlines(arg.get(3)); + } + + getSystem().addMessage(new Message(p1, p2, labels, dotted, full, getSystem().getNextMessageNumber())); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutoNewpage.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutoNewpage.java new file mode 100644 index 000000000..34dfd84de --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutoNewpage.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandAutoNewpage extends SingleLineCommand { + + public CommandAutoNewpage(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^autonewpage\\s+(\\d+)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + getSystem().setAutonewpage(Integer.parseInt(arg.get(0))); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java new file mode 100644 index 000000000..38f902e24 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandAutonumber.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.text.DecimalFormat; +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandAutonumber extends SingleLineCommand { + + public CommandAutonumber(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^autonumber\\s*(\\d+)?(?:\\s+(\\d+))?(?:\\s+\"([^\"]+)\")?\\s*$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + int start = 1; + if (arg.get(0) != null) { + start = Integer.parseInt(arg.get(0)); + } + int inc = 1; + if (arg.get(1) != null) { + inc = Integer.parseInt(arg.get(1)); + } + + final String df = arg.get(2) == null ? "0" : arg.get(2); + final DecimalFormat decimalFormat = new DecimalFormat(df); + + getSystem().goAutonumber(start, inc, decimalFormat); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxEnd.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxEnd.java new file mode 100644 index 000000000..afbfac3f3 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxEnd.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandBoxEnd extends SingleLineCommand { + + public CommandBoxEnd(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^end ?box$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().isBoxPending() == false) { + return CommandExecutionResult.error("Missing starting box"); + } + getSystem().endBox(); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java new file mode 100644 index 000000000..d9f31ac2d --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandBoxStart.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandBoxStart extends SingleLineCommand { + + public CommandBoxStart(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^box(?:\\s+\"([^\"]+)\")?(?:\\s+(#\\w+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().isBoxPending()) { + return CommandExecutionResult.error("Box cannot be nested"); + } + final HtmlColor color = HtmlColor.getColorIfValid(arg.get(1)); + final String title = arg.get(0) == null ? "" : arg.get(0); + getSystem().boxStart(StringUtils.getWithNewlines(title), color); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandDivider.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandDivider.java new file mode 100644 index 000000000..b0ec8d10d --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandDivider.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandDivider extends SingleLineCommand { + + public CommandDivider(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^==\\s*(.+)\\s*==$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final List strings = StringUtils.getWithNewlines(arg.get(0)); + getSystem().divider(strings); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java new file mode 100644 index 000000000..78e695c16 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.MessageExo; +import net.sourceforge.plantuml.sequencediagram.MessageExoType; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +abstract class CommandExoArrowAny extends SingleLineCommand { + + private final int posArrow; + private final int posParticipant; + + public CommandExoArrowAny(SequenceDiagram sequenceDiagram, String pattern, int posArrow, int posParticipant) { + super(sequenceDiagram, pattern); + this.posArrow = posArrow; + this.posParticipant = posParticipant; + } + + @Override + final protected CommandExecutionResult executeArg(List arg) { + final String arrow = StringUtils.manageArrowForSequence(arg.get(posArrow)); + final Participant p = getSystem().getOrCreateParticipant(arg.get(posParticipant)); + + final boolean full = (arrow.endsWith(">>") || arrow.startsWith("<<")) == false; + final boolean dotted = arrow.contains("--"); + + final List labels; + if (arg.get(2) == null) { + labels = Arrays.asList(""); + } else { + labels = StringUtils.getWithNewlines(arg.get(2)); + } + + getSystem().addMessage( + new MessageExo(p, getMessageExoType(arrow), labels, dotted, + full, getSystem().getNextMessageNumber())); + return CommandExecutionResult.ok(); + } + + final MessageExoType getMessageExoType(String arrow) { + if (arrow.startsWith("[") && arrow.endsWith(">")) { + return MessageExoType.FROM_LEFT; + } + if (arrow.startsWith("[<")) { + return MessageExoType.TO_LEFT; + } + if (arrow.startsWith("<") && arrow.endsWith("]")) { + return MessageExoType.FROM_RIGHT; + } + if (arrow.endsWith(">]")) { + return MessageExoType.TO_RIGHT; + } + throw new IllegalArgumentException(arrow); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java new file mode 100644 index 000000000..8a5594916 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandExoArrowLeft extends CommandExoArrowAny { + + public CommandExoArrowLeft(SequenceDiagram sequenceDiagram) { + super( + sequenceDiagram, + "(?i)^(\\[[=-]+>{1,2}|\\[\\<{1,2}[=-]+)\\s*([\\p{L}0-9_.]+)\\s*(?::\\s*(.*))?$", + 0, 1); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java new file mode 100644 index 000000000..0c095c250 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandExoArrowRight extends CommandExoArrowAny { + + public CommandExoArrowRight(SequenceDiagram sequenceDiagram) { + super( + sequenceDiagram, + "(?i)^([\\p{L}0-9_.]+)\\s*([=-]+>{1,2}\\]|\\<{1,2}[=-]+\\])\\s*(?::\\s*(.*))?$", + 1, 0); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandFootbox.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandFootbox.java new file mode 100644 index 000000000..47cf628fb --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandFootbox.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5158 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandFootbox extends SingleLineCommand { + + public CommandFootbox(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^(hide|show)?\\s*footbox?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final boolean footbox = arg.get(0).equalsIgnoreCase("show"); + getSystem().setShowFootbox(footbox); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandFootboxOld.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandFootboxOld.java new file mode 100644 index 000000000..c7c980048 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandFootboxOld.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandFootboxOld extends SingleLineCommand { + + public CommandFootboxOld(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^footbox\\s*(on|off)?\\s*$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final boolean footbox = arg.get(0).equalsIgnoreCase("on"); + getSystem().setShowFootbox(footbox); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java new file mode 100644 index 000000000..8cf13b3bc --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandGrouping.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5533 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.sequencediagram.GroupingType; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandGrouping extends SingleLineCommand { + + public CommandGrouping(SequenceDiagram sequenceDiagram) { + super( + sequenceDiagram, + "(?i)^(opt|alt|loop|par|break|critical|else|end|group)((? arg) { + final String type = arg.get(0).toLowerCase(); + final HtmlColor colorElement = HtmlColor.getColorIfValid(arg.get(1)); + final HtmlColor colorGeneral = HtmlColor.getColorIfValid(arg.get(2)); + String comment = arg.get(3); + if ("group".equals(type) && StringUtils.isEmpty(comment)) { + comment = "group"; + } + final boolean result = getSystem().grouping(type, comment, + GroupingType.getType(type), colorGeneral, colorElement); + if (result == false) { + return CommandExecutionResult.error("Cannot create group"); + } + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandIgnoreNewpage.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandIgnoreNewpage.java new file mode 100644 index 000000000..12b24fc26 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandIgnoreNewpage.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandIgnoreNewpage extends SingleLineCommand { + + public CommandIgnoreNewpage(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^ignore\\s*newpage$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + getSystem().ignoreNewpage(); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java new file mode 100644 index 000000000..65ac946d0 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.sequencediagram.Note; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandMultilinesNote extends CommandMultilines { + + public CommandMultilinesNote(final SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^note\\s+(right|left|over)\\s+(?:of\\s+)?([\\p{L}0-9_.]+)\\s*(#\\w+)?$", "(?i)^end ?note$"); + } + + public CommandExecutionResult execute(List lines) { + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final Participant p = getSystem().getOrCreateParticipant(line0.get(1)); + + final NotePosition position = NotePosition.valueOf(line0.get(0).toUpperCase()); + + final List strings = lines.subList(1, lines.size() - 1); + if (strings.size() > 0) { + final Note note = new Note(p, position, strings); + note.setSpecificBackcolor(line0.get(2)); + + getSystem().addNote(note); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java new file mode 100644 index 000000000..3b7233772 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.sequencediagram.AbstractMessage; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandMultilinesNoteOnArrow extends CommandMultilines { + + public CommandMultilinesNoteOnArrow(final SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^note\\s+(right|left)\\s*(#\\w+)?$", "(?i)^end ?note$"); + } + + public CommandExecutionResult execute(List lines) { + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + + final NotePosition position = NotePosition.valueOf(line0.get(0).toUpperCase()); + final AbstractMessage m = getSystem().getLastMessage(); + if (m != null) { + final List strings = lines.subList(1, lines.size() - 1); + m.setNote(strings, position, line0.get(1)); + } + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java new file mode 100644 index 000000000..606c19942 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.sequencediagram.Note; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandMultilinesNoteOverSeveral extends CommandMultilines { + + public CommandMultilinesNoteOverSeveral(final SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^note\\s+over\\s+([\\p{L}0-9_.]+)\\s*\\,\\s*([\\p{L}0-9_.]+)\\s*(#\\w+)?$", "(?i)^end ?note$"); + } + + public CommandExecutionResult execute(List lines) { + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + + final Participant p1 = getSystem().getOrCreateParticipant(line0.get(0)); + final Participant p2 = getSystem().getOrCreateParticipant(line0.get(1)); + + final List strings = lines.subList(1, lines.size() - 1); + if (strings.size() > 0) { + final Note note = new Note(p1, p2, strings); + note.setSpecificBackcolor(line0.get(2)); + getSystem().addNote(note); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNewpage.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNewpage.java new file mode 100644 index 000000000..1ad9cb5ec --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNewpage.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandNewpage extends SingleLineCommand { + + public CommandNewpage(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^@?newpage(?:(?:\\s*:\\s*|\\s+)(.*[\\p{L}0-9_.].*))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final List strings = arg.get(0) == null ? null : StringUtils.getWithNewlines(arg.get(0)); + getSystem().newpage(strings); + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOnArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOnArrow.java new file mode 100644 index 000000000..af8314d7b --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOnArrow.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.AbstractMessage; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandNoteOnArrow extends SingleLineCommand { + + public CommandNoteOnArrow(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^note\\s+(right|left)\\s*(#\\w+)?\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + + final AbstractMessage m = getSystem().getLastMessage(); + if (m != null) { + final NotePosition position = NotePosition.valueOf(arg.get(0).toUpperCase()); + final List strings = StringUtils.getWithNewlines(arg.get(2)); + m.setNote(strings, position, arg.get(1)); + } + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java new file mode 100644 index 000000000..1e8ef9048 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java @@ -0,0 +1,62 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.Note; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandNoteOverSeveral extends SingleLineCommand { + + public CommandNoteOverSeveral(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^note\\s+over\\s+([\\p{L}0-9_.]+)\\s*\\,\\s*([\\p{L}0-9_.]+)\\s*(#\\w+)?\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Participant p1 = getSystem().getOrCreateParticipant(arg.get(0)); + final Participant p2 = getSystem().getOrCreateParticipant(arg.get(1)); + final List strings = StringUtils.getWithNewlines(arg.get(3)); + final Note note = new Note(p1, p2, strings); + note.setSpecificBackcolor(arg.get(2)); + getSystem().addNote(note); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java new file mode 100644 index 000000000..1bc452256 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.Note; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandNoteSequence extends SingleLineCommand { + + public CommandNoteSequence(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, "(?i)^note\\s+(right|left|over)\\s+(?:of\\s+)?([\\p{L}0-9_.]+)\\s*(#\\w+)?\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Participant p = getSystem().getOrCreateParticipant(arg.get(1)); + + final NotePosition position = NotePosition.valueOf(arg.get(0).toUpperCase()); + + final List strings = StringUtils.getWithNewlines(arg.get(3)); + final Note note = new Note(p, position, strings); + note.setSpecificBackcolor(arg.get(2)); + getSystem().addNote(note); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java new file mode 100644 index 000000000..c9840c1b6 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.ParticipantType; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandParticipant extends SingleLineCommand { + + public CommandParticipant(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, + "(?i)^(participant|actor)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)(?:\\s*(\\<\\<.*\\>\\>))?\\s*(#\\w+)?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(2); + if (getSystem().participants().containsKey(code)) { + return CommandExecutionResult.error("Duplicate participant : "+code); + } + + List strings = null; + if (arg.get(1) != null) { + strings = StringUtils.getWithNewlines(arg.get(1)); + } + + final ParticipantType type = ParticipantType.valueOf(arg.get(0).toUpperCase()); + final Participant participant = getSystem().createNewParticipant(type, code, strings); + + final String stereotype = arg.get(3); + + if (stereotype != null) { + participant.setStereotype(new Stereotype(stereotype, + getSystem().getSkinParam().getCircledCharacterRadius(), getSystem().getSkinParam().getFont( + FontParam.CIRCLED_CHARACTER))); + } + participant.setSpecificBackcolor(arg.get(4)); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java new file mode 100644 index 000000000..f1216ea70 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.ParticipantType; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandParticipant2 extends SingleLineCommand { + + public CommandParticipant2(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, + "(?i)^(participant|actor)\\s+([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"(?:\\s*(\\<\\<.*\\>\\>))?\\s*(#\\w+)?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(1); + if (getSystem().participants().containsKey(code)) { + return CommandExecutionResult.error("Duplicate participant : " + code); + } + + final List strings = StringUtils.getWithNewlines(arg.get(2)); + + final ParticipantType type = ParticipantType.valueOf(arg.get(0).toUpperCase()); + final Participant participant = getSystem().createNewParticipant(type, code, strings); + + final String stereotype = arg.get(3); + + if (stereotype != null) { + participant.setStereotype(new Stereotype(stereotype, + getSystem().getSkinParam().getCircledCharacterRadius(), getSystem().getSkinParam().getFont( + FontParam.CIRCLED_CHARACTER))); + } + participant.setSpecificBackcolor(arg.get(4)); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandSkin.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandSkin.java new file mode 100644 index 000000000..da5d0e699 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandSkin.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandSkin extends SingleLineCommand { + + public CommandSkin(SequenceDiagram system) { + super(system, "(?i)^skin\\s+([\\w.]+)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().changeSkin(arg.get(0))) { + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("Cannot change skin"); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java new file mode 100644 index 000000000..5d7a707b9 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java @@ -0,0 +1,99 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4855 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Skin; + +abstract class Arrow extends GraphicalElement implements InGroupable { + + private final Skin skin; + private final Component arrowComponent; + private double paddingArrowHead = 0; + private double maxX; + + public void setMaxX(double m) { + if (maxX != 0) { + throw new IllegalStateException(); + } + this.maxX = m; + } + + final protected double getMaxX() { + if (maxX == 0) { + throw new IllegalStateException(); + } + return maxX; + } + + public abstract double getActualWidth(StringBounder stringBounder); + + Arrow(double startingY, Skin skin, Component arrowComponent) { + super(startingY); + this.skin = skin; + this.arrowComponent = arrowComponent; + } + + public abstract int getDirection(StringBounder stringBounder); + + protected Skin getSkin() { + return skin; + } + + protected final Component getArrowComponent() { + return arrowComponent; + } + + public double getArrowOnlyWidth(StringBounder stringBounder) { + return getPreferredWidth(stringBounder); + } + + public abstract double getArrowYStartLevel(StringBounder stringBounder); + + public abstract double getArrowYEndLevel(StringBounder stringBounder); + + public abstract LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position); + + protected final double getPaddingArrowHead() { + return paddingArrowHead; + } + + protected final void setPaddingArrowHead(double paddingArrowHead) { + this.paddingArrowHead = paddingArrowHead; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java new file mode 100644 index 000000000..45ff6d824 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java @@ -0,0 +1,138 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4855 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class ArrowAndNoteBox extends Arrow implements InGroupable { + + private final Arrow arrow; + private final NoteBox noteBox; + + public ArrowAndNoteBox(StringBounder stringBounder, Arrow arrow, NoteBox noteBox) { + super(arrow.getStartingY(), arrow.getSkin(), arrow.getArrowComponent()); + this.arrow = arrow; + this.noteBox = noteBox; + + final double arrowHeight = arrow.getPreferredHeight(stringBounder); + final double noteHeight = noteBox.getPreferredHeight(stringBounder); + final double myHeight = getPreferredHeight(stringBounder); + + final double diffHeightArrow = myHeight - arrowHeight; + final double diffHeightNote = myHeight - noteHeight; + if (diffHeightArrow > 0) { + arrow.pushToDown(-diffHeightArrow / 2); + } + if (diffHeightNote > 0) { + noteBox.pushToDown(-diffHeightNote / 2); + } + } + + @Override + final public double getArrowOnlyWidth(StringBounder stringBounder) { + return arrow.getPreferredWidth(stringBounder); + } + + @Override + public void setMaxX(double m) { + super.setMaxX(m); + arrow.setMaxX(m); + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + arrow.drawU(ug, maxX, context); + noteBox.drawU(ug, maxX, context); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return Math.max(arrow.getPreferredHeight(stringBounder), noteBox.getPreferredHeight(stringBounder)); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + double w = arrow.getPreferredWidth(stringBounder); + w = Math.max(w, arrow.getActualWidth(stringBounder)); + return w + noteBox.getPreferredWidth(stringBounder); + } + + @Override + public double getActualWidth(StringBounder stringBounder) { + return getPreferredWidth(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return Math.min(arrow.getStartingX(stringBounder), noteBox.getStartingX(stringBounder)); + } + + @Override + public int getDirection(StringBounder stringBounder) { + return arrow.getDirection(stringBounder); + } + + @Override + public double getArrowYStartLevel(StringBounder stringBounder) { + return arrow.getArrowYStartLevel(stringBounder); + } + + @Override + public double getArrowYEndLevel(StringBounder stringBounder) { + return arrow.getArrowYEndLevel(stringBounder); + } + + public double getMaxX(StringBounder stringBounder) { + return getStartingX(stringBounder) + getPreferredWidth(stringBounder); + } + + public double getMinX(StringBounder stringBounder) { + return getStartingX(stringBounder); + } + + public String toString(StringBounder stringBounder) { + return toString(); + } + + @Override + public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position) { + return arrow.getParticipantAt(stringBounder, position); + } + + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java new file mode 100644 index 000000000..8b80a06d2 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java @@ -0,0 +1,134 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4721 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class ArrowAndParticipant extends Arrow implements InGroupable { + + private final Arrow arrow; + private final ParticipantBox participantBox; + + public ArrowAndParticipant(StringBounder stringBounder, Arrow arrow, ParticipantBox participantBox) { + super(arrow.getStartingY(), arrow.getSkin(), arrow.getArrowComponent()); + this.arrow = arrow; + this.participantBox = participantBox; + //participantBox.setDeltaHead(arrow.getStartingY()); + arrow.setPaddingArrowHead(participantBox.getPreferredWidth(stringBounder) / 2); + // participantBox.setTopStartingY(arrow.getStartingY()); + + } + + @Override + public void setMaxX(double m) { + super.setMaxX(m); + arrow.setMaxX(m); + } + + + @Override + final public double getArrowOnlyWidth(StringBounder stringBounder) { + return arrow.getPreferredWidth(stringBounder) + participantBox.getPreferredWidth(stringBounder) / 2; + } + + @Override + public double getArrowYEndLevel(StringBounder stringBounder) { + return arrow.getArrowYEndLevel(stringBounder); + } + + @Override + public double getArrowYStartLevel(StringBounder stringBounder) { + return arrow.getArrowYStartLevel(stringBounder); + } + + @Override + public int getDirection(StringBounder stringBounder) { + return arrow.getDirection(stringBounder); + } + + @Override + public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position) { + return arrow.getParticipantAt(stringBounder, position); + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + arrow.drawInternalU(ug, maxX, context); + ug.setTranslate(atX, atY); + //ug.translate(getStartingX(ug.getStringBounder()), getStartingY()); + ug.translate(participantBox.getStartingX(), getStartingY()); + participantBox.drawParticipantHead(ug); + + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return Math.max(arrow.getPreferredHeight(stringBounder), participantBox.getHeadHeight(stringBounder)); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return arrow.getPreferredWidth(stringBounder) + participantBox.getPreferredWidth(stringBounder) / 2; + } + + @Override + public double getActualWidth(StringBounder stringBounder) { + return arrow.getActualWidth(stringBounder) + participantBox.getPreferredWidth(stringBounder) / 2; + } + + + @Override + public double getStartingX(StringBounder stringBounder) { + return arrow.getStartingX(stringBounder); + } + + public double getMaxX(StringBounder stringBounder) { + return arrow.getMaxX(stringBounder); + } + + public double getMinX(StringBounder stringBounder) { + return arrow.getMinX(stringBounder); + } + + public String toString(StringBounder stringBounder) { + return arrow.toString(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Constraint.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Constraint.java new file mode 100644 index 000000000..be7433695 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Constraint.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4683 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +class Constraint { + + private final Pushable p1; + private final Pushable p2; + private double value; + + public Constraint(Pushable p1, Pushable p2) { + if (p1 == null || p2 == null) { + throw new IllegalArgumentException(); + } + this.p1 = p1; + this.p2 = p2; + } + + public final Pushable getParticipant1() { + return p1; + } + + public final Pushable getParticipant2() { + return p2; + } + + public final double getValue() { + return value; + } + + public final void ensureValue(double newValue) { + if (newValue > value) { + this.value = newValue; + } + } + + public void push(double delta) { + value += delta; + } + + @Override + public String toString() { + return "Constraint " + p1 + " " + p2 + " " + value; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSet.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSet.java new file mode 100644 index 000000000..f76abb83b --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSet.java @@ -0,0 +1,183 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5251 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.graphic.StringBounder; + +class ConstraintSet { + + private final ParticipantBoxSimple firstBorder; + + private final ParticipantBoxSimple lastborder; + + final private List participantList = new ArrayList(); + final private Map, Constraint> constraints = new HashMap, Constraint>(); + + public ConstraintSet(Collection all, double freeX) { + this.participantList.add(firstBorder = new ParticipantBoxSimple(0, "LEFT")); + this.participantList.addAll(all); + this.participantList.add(lastborder = new ParticipantBoxSimple(freeX, "RIGHT")); + } + + @Override + public String toString() { + return constraints.values().toString(); + } + + public double getMaxX() { + return lastborder.getCenterX(null); + } + + public Constraint getConstraint(Pushable p1, Pushable p2) { + if (p1 == null || p2 == null || p1 == p2) { + throw new IllegalArgumentException(); + } + final int i1 = participantList.indexOf(p1); + final int i2 = participantList.indexOf(p2); + if (i1 == -1 || i2 == -1) { + throw new IllegalArgumentException(); + } + if (i1 > i2) { + return getConstraint(p2, p1); + } + final List key = Arrays.asList(p1, p2); + Constraint result = constraints.get(key); + if (result == null) { + result = new Constraint(p1, p2); + constraints.put(key, result); + } + return result; + } + + public Constraint getConstraintAfter(Pushable p1) { + if (p1 == null) { + throw new IllegalArgumentException(); + } + return getConstraint(p1, getNext(p1)); + } + + public Constraint getConstraintBefore(Pushable p1) { + if (p1 == null) { + throw new IllegalArgumentException(); + } + return getConstraint(p1, getPrevious(p1)); + } + + public Pushable getPrevious(Pushable p) { + return getOtherParticipant(p, -1); + } + + public Pushable getNext(Pushable p) { + return getOtherParticipant(p, 1); + } + + + private Pushable getOtherParticipant(Pushable p, int delta) { + final int i = participantList.indexOf(p); + if (i == -1) { + throw new IllegalArgumentException(); + } + return participantList.get(i + delta); + } + + public void takeConstraintIntoAccount(StringBounder stringBounder) { + for (int dist = 1; dist < participantList.size(); dist++) { + pushEverybody(stringBounder, dist); + } + } + + private void pushEverybody(StringBounder stringBounder, int dist) { + for (int i = 0; i < participantList.size() - dist; i++) { + final Pushable p1 = participantList.get(i); + final Pushable p2 = participantList.get(i + dist); + final Constraint c = getConstraint(p1, p2); + ensureSpaceAfter(stringBounder, p1, p2, c.getValue()); + } + } + + private void pushToLeftParticipantBox(double deltaX, Pushable firstToChange) { + if (deltaX <= 0) { + throw new IllegalArgumentException(); + } + if (firstToChange == null) { + throw new IllegalArgumentException(); + } + // freeX += deltaX; + boolean founded = false; + for (Pushable box : participantList) { + if (box.equals(firstToChange)) { + founded = true; + } + if (founded) { + box.pushToLeft(deltaX); + } + } + } + + public void pushToLeft(double delta) { + pushToLeftParticipantBox(delta, firstBorder); + } + + private void ensureSpaceAfter(StringBounder stringBounder, Pushable p1, Pushable p2, double space) { + if (p1.equals(p2)) { + throw new IllegalArgumentException(); + } + if (p1.getCenterX(stringBounder) > p2.getCenterX(stringBounder)) { + ensureSpaceAfter(stringBounder, p2, p1, space); + return; + } + assert p1.getCenterX(stringBounder) < p2.getCenterX(stringBounder); + final double existingSpace = p2.getCenterX(stringBounder) - p1.getCenterX(stringBounder); + if (existingSpace < space) { + pushToLeftParticipantBox(space - existingSpace, p2); + } + + } + + public final Pushable getFirstBorder() { + return firstBorder; + } + + public final Pushable getLastborder() { + return lastborder; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSetHBar.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSetHBar.java new file mode 100644 index 000000000..742e53f98 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSetHBar.java @@ -0,0 +1,117 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; + +class ConstraintSetHBar { + + final private List pushables = new ArrayList(); + final private List inGroupableLists = new ArrayList(); + + public ConstraintSetHBar(Collection all) { + this.pushables.addAll(all); + } + + public void add(InGroupableList inGroupableList) { + this.inGroupableLists.add(inGroupableList); + } + + public double takeConstraintIntoAccount(StringBounder stringBounder, double freeX) { + for (InGroupableList list : inGroupableLists) { + if (list.isEmpty()) { + list.getBarEnd().pushToLeft(list.getMaxX(stringBounder)); + continue; + } + final ParticipantBox first = list.getFirstParticipantBox(); + final ParticipantBox last = list.getLastParticipantBox(); + final int idxFirst = pushables.indexOf(first); + final int idxLast = pushables.indexOf(last); + if (idxFirst == -1 || idxLast == -1) { + throw new IllegalStateException(); + } + pushables.add(idxFirst, list.getBarStart()); + pushables.add(idxLast + 2, list.getBarEnd()); + list.getBarStart().pushToLeft(list.getMinX(stringBounder)); + list.getBarEnd().pushToLeft(list.getMaxX(stringBounder)); + } + + double result = freeX; + for (int i = 0; i < pushables.size(); i++) { + final Pushable pushable = pushables.get(i); + if (pushable instanceof VirtualHBar) { + final VirtualHBar bar = (VirtualHBar) pushable; + final int j = getVirtualNext(i); + pushAllToLeft(j, bar.getWidth()); + result += bar.getWidth(); + i = j; + } + } + + for (InGroupableList list : inGroupableLists) { + final double endBar = list.getBarEnd().getCenterX(stringBounder) + 5; + if (endBar > result) { + result = endBar; + } + } + + return result; + } + + private int getVirtualNext(int i) { + final VirtualHBar ref = (VirtualHBar) pushables.get(i); + for (int j = i + 1; j < pushables.size(); j++) { + if (pushables.get(j) instanceof VirtualHBar == false) { + return j - 1; + } + final VirtualHBar other = (VirtualHBar) pushables.get(j); + if (other.canBeOnTheSameLine(ref) == false) { + return j - 1; + } + } + return pushables.size() - 1; + } + + private void pushAllToLeft(int afterThisOne, double deltaX) { + for (int i = afterThisOne + 1; i < pushables.size(); i++) { + pushables.get(i).pushToLeft(deltaX); + } + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java new file mode 100644 index 000000000..a96ad3ff9 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java @@ -0,0 +1,390 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5271 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.Event; +import net.sourceforge.plantuml.sequencediagram.Newpage; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class DrawableSet { + + private final Map participants = new LinkedHashMap(); + private final Map events = new HashMap(); + private final List participantEnglobers = new ArrayList(); + private final List eventsList = new ArrayList(); + private final Skin skin; + private final ISkinParam skinParam; + private Dimension2D dimension; + private double topStartingY; + + DrawableSet(Skin skin, ISkinParam skinParam) { + if (skin == null) { + throw new IllegalArgumentException(); + } + if (skinParam == null) { + throw new IllegalArgumentException(); + } + this.skin = skin; + this.skinParam = skinParam; + } + + public final Skin getSkin() { + return skin; + } + + public final ISkinParam getSkinParam() { + return skinParam; + } + + public Collection getAllEvents() { + return Collections.unmodifiableCollection(eventsList); + } + + public Set getAllParticipants() { + return Collections.unmodifiableSet(participants.keySet()); + } + + public Collection getAllLivingParticipantBox() { + return Collections.unmodifiableCollection(participants.values()); + } + + public Collection getAllGraphicalElements() { + final Collection result = new ArrayList(); + for (Event ev : eventsList) { + result.add(events.get(ev)); + } + return Collections.unmodifiableCollection(result); + } + + public LivingParticipantBox getLivingParticipantBox(Participant p) { + return participants.get(p); + } + + public GraphicalElement getEvent(Event ev) { + return events.get(ev); + } + + // public double getHeadHeightOld(StringBounder stringBounder) { + // double r = 0; + // for (LivingParticipantBox livingParticipantBox : participants.values()) { + // final double y = + // livingParticipantBox.getParticipantBox().getHeadHeight(stringBounder); + // r = Math.max(r, y); + // } + // return r; + // } + + public double getHeadHeight(StringBounder stringBounder) { + double r = 0; + for (Participant p : participants.keySet()) { + final double y = getHeadAndEngloberHeight(p, stringBounder); + r = Math.max(r, y); + } + return r; + } + + public double getHeadAndEngloberHeight(Participant p, StringBounder stringBounder) { + final LivingParticipantBox box = participants.get(p); + final double height = box.getParticipantBox().getHeadHeight(stringBounder); + final ParticipantEnglober englober = getParticipantEnglober(p); + if (englober == null) { + return height; + } + final Component comp = skin.createComponent(ComponentType.ENGLOBER, skinParam, englober.getTitle()); + final double heightEnglober = comp.getPreferredHeight(stringBounder); + return height + heightEnglober; + } + + public double getOffsetForEnglobers(StringBounder stringBounder) { + double result = 0; + for (ParticipantEnglober englober : participantEnglobers) { + final Component comp = skin.createComponent(ComponentType.ENGLOBER, skinParam, englober.getTitle()); + final double height = comp.getPreferredHeight(stringBounder); + if (height > result) { + result = height; + } + } + return result; + } + + static private final int MARGIN_FOR_ENGLOBERS = 4; + static private final int MARGIN_FOR_ENGLOBERS1 = 2; + + public double getTailHeight(StringBounder stringBounder, boolean showTail) { + final double marginForEnglobers = this.participantEnglobers.size() > 0 ? MARGIN_FOR_ENGLOBERS : 0; + + if (showTail == false) { + return 1 + marginForEnglobers; + } + double r = 0; + for (LivingParticipantBox livingParticipantBox : participants.values()) { + final double y = livingParticipantBox.getParticipantBox().getTailHeight(stringBounder); + r = Math.max(r, y); + } + return r + marginForEnglobers; + } + + public void addParticipant(Participant p, LivingParticipantBox box) { + participants.put(p, box); + } + + public void addEvent(Event event, GraphicalElement object) { + if (events.keySet().contains(event) == false) { + eventsList.add(event); + } + events.put(event, object); + } + + public void addEvent(Newpage newpage, GraphicalNewpage object, Event justBefore) { + final int idx = eventsList.indexOf(justBefore); + if (idx == -1) { + throw new IllegalArgumentException(); + } + eventsList.add(idx, newpage); + events.put(newpage, object); + assert events.size() == eventsList.size(); + } + + void setDimension(Dimension2D dim) { + if (dimension != null) { + throw new IllegalStateException(); + } + this.dimension = dim; + } + + public Dimension2D getDimension() { + return dimension; + } + + void drawU(UGraphic ug, final double delta, double width, Page page, boolean showTail) { + + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + + final int height = (int) page.getHeight(); + + clipAndTranslate(delta, width, page, ug); + this.drawPlaygroundU(ug, height, new SimpleContext2D(true)); + ug.setClip(null); + ug.setTranslate(atX, atY); + this.drawEnglobers(ug, height - MARGIN_FOR_ENGLOBERS1, new SimpleContext2D(true)); + // ug.setClip(null); + // ug.setTranslate(atX, atY); + + this.drawLineU(ug, showTail, page); + this.drawHeadTailU(ug, page, showTail ? height - getTailHeight(ug.getStringBounder(), true) : 0); + + clipAndTranslate(delta, width, page, ug); + this.drawPlaygroundU(ug, height, new SimpleContext2D(false)); + ug.setClip(null); + } + + private void clipAndTranslate(final double delta, double width, Page p, final UGraphic ug) { + ug.setClip(new UClip(0, p.getBodyRelativePosition(), width, p.getBodyHeight() + 1)); + if (delta > 0) { + ug.translate(0, -delta); + } + } + + private void drawLineU(UGraphic ug, boolean showTail, Page page) { + for (LivingParticipantBox box : getAllLivingParticipantBox()) { + final double create = box.getCreate(); + final double startMin = page.getBodyRelativePosition() - box.magicMargin(ug.getStringBounder()); + // final double endMax = page.getHeight() - 1; + final double endMax = startMin + page.getBodyHeight() + 2 * box.magicMargin(ug.getStringBounder()); + double start = startMin; + if (create > 0) { + if (create > page.getNewpage2()) { + continue; + } + if (create >= page.getNewpage1() && create < page.getNewpage2()) { + start += create - page.getNewpage1() + 2 * box.magicMargin(ug.getStringBounder()); + } + } + box.drawLineU(ug, start, endMax, showTail); + } + } + + private void drawHeadTailU(UGraphic ug, Page page, double positionTail) { + for (LivingParticipantBox box : getAllLivingParticipantBox()) { + final double create = box.getCreate(); + boolean showHead = true; + if (create > 0) { + if (create > page.getNewpage2()) { + continue; + } + if (create >= page.getNewpage1() && create < page.getNewpage2()) { + showHead = false; + } + } + box.getParticipantBox().drawHeadTailU(ug, topStartingY, showHead, positionTail); + } + } + + private double getMaxX() { + return dimension.getWidth(); + } + + private double getMaxY() { + return dimension.getHeight(); + } + + private void drawPlaygroundU(UGraphic ug, double height, Context2D context) { + for (Participant p : getAllParticipants()) { + drawLifeLineU(ug, p); + } + + for (GraphicalElement element : getAllGraphicalElements()) { + element.drawU(ug, getMaxX(), context); + } + } + + private void drawEnglobers(UGraphic ug, double height, Context2D context) { + for (ParticipantEnglober englober : participantEnglobers) { + double x1 = getX1(englober); + final double x2 = getX2(ug.getStringBounder(), englober); + + final Component comp = getEngloberComponent(englober); + + final double width = x2 - x1; + final double preferedWidth = getEngloberPreferedWidth(ug.getStringBounder(), englober); + if (preferedWidth > width) { + if (englober.getFirst() == englober.getLast()) { + x1 -= (preferedWidth - width) / 2; + } + final Dimension2DDouble dim = new Dimension2DDouble(preferedWidth, height); + ug.translate(x1, 1); + comp.drawU(ug, dim, context); + ug.translate(-x1, -1); + } else { + final Dimension2DDouble dim = new Dimension2DDouble(width, height); + ug.translate(x1, 1); + comp.drawU(ug, dim, context); + ug.translate(-x1, -1); + } + } + } + + public double getEngloberPreferedWidth(StringBounder stringBounder, ParticipantEnglober englober) { + return getEngloberComponent(englober).getPreferredWidth(stringBounder); + } + + private Component getEngloberComponent(ParticipantEnglober englober) { + final ISkinParam s = englober.getBoxColor() == null ? skinParam : new SkinParamBackcolored(skinParam, englober + .getBoxColor()); + return skin.createComponent(ComponentType.ENGLOBER, s, englober.getTitle()); + } + + private double getX1(ParticipantEnglober englober) { + final Participant first = englober.getFirst(); + final ParticipantBox firstBox = participants.get(first).getParticipantBox(); + return firstBox.getStartingX() + 1; + } + + private double getX2(StringBounder stringBounder, ParticipantEnglober englober) { + final Participant last = englober.getLast(); + final ParticipantBox lastBox = participants.get(last).getParticipantBox(); + return lastBox.getMaxX(stringBounder) - 1; + } + + private void drawLifeLineU(UGraphic ug, Participant p) { + final LifeLine line = getLivingParticipantBox(p).getLifeLine(); + + line.finish(getMaxY()); + line.drawU(ug, getSkin(), skinParam); + } + + public void addParticipantEnglober(ParticipantEnglober englober) { + participantEnglobers.add(englober); + } + + private boolean contains(ParticipantEnglober englober, Participant toTest) { + if (toTest == englober.getFirst() || toTest == englober.getLast()) { + return true; + } + boolean inside = false; + for (Participant p : participants.keySet()) { + if (p == englober.getFirst()) { + inside = true; + } + if (p == toTest) { + return inside; + } + if (p == englober.getLast()) { + inside = false; + } + } + throw new IllegalArgumentException(); + } + + private ParticipantEnglober getParticipantEnglober(Participant p) { + for (ParticipantEnglober pe : participantEnglobers) { + if (contains(pe, p)) { + return pe; + } + } + return null; + } + + public void setTopStartingY(double topStartingY) { + this.topStartingY = topStartingY; + } + + public final List getParticipantEnglobers() { + return Collections.unmodifiableList(participantEnglobers); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java new file mode 100644 index 000000000..b3c9b14dd --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java @@ -0,0 +1,427 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5528 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.Divider; +import net.sourceforge.plantuml.sequencediagram.Event; +import net.sourceforge.plantuml.sequencediagram.GroupingLeaf; +import net.sourceforge.plantuml.sequencediagram.GroupingStart; +import net.sourceforge.plantuml.sequencediagram.GroupingType; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.sequencediagram.LifeEvent; +import net.sourceforge.plantuml.sequencediagram.LifeEventType; +import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.MessageExo; +import net.sourceforge.plantuml.sequencediagram.Newpage; +import net.sourceforge.plantuml.sequencediagram.Note; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober; +import net.sourceforge.plantuml.sequencediagram.ParticipantType; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Skin; + +class DrawableSetInitializer { + + private final DrawableSet drawableSet; + private final boolean showTail; + + private double freeX = 0; + private double freeY = 0; + + private final double groupingMargin = 10; + private final double autonewpage; + + private int maxGrouping = 0; + + private ConstraintSet constraintSet; + private ConstraintSetHBar constraintSetHBar; + + public DrawableSetInitializer(Skin skin, ISkinParam skinParam, boolean showTail, double autonewpage) { + this.drawableSet = new DrawableSet(skin, skinParam); + this.showTail = showTail; + this.autonewpage = autonewpage; + + } + + private double lastFreeY = 0; + + public DrawableSet createDrawableSet(StringBounder stringBounder) { + if (freeY != 0) { + throw new IllegalStateException(); + } + + for (Participant p : drawableSet.getAllParticipants()) { + prepareParticipant(stringBounder, p); + } + + this.freeY = drawableSet.getHeadHeight(stringBounder); + // this.freeY += drawableSet.getOffsetForEnglobers(stringBounder); + this.lastFreeY = this.freeY; + + drawableSet.setTopStartingY(this.freeY); + + // for (LivingParticipantBox p : + // drawableSet.getAllLivingParticipantBox()) { + // p.getParticipantBox().setTopStartingY(this.freeY); + // } + + for (Participant p : drawableSet.getAllParticipants()) { + final LivingParticipantBox living = drawableSet.getLivingParticipantBox(p); + for (int i = 0; i < p.getInitialLife(); i++) { + living.getLifeLine().addSegmentVariation(LifeSegmentVariation.LARGER, this.freeY, + p.getLiveSpecificBackColor()); + } + } + + final Collection col = new ArrayList(); + for (LivingParticipantBox livingParticipantBox : drawableSet.getAllLivingParticipantBox()) { + col.add(livingParticipantBox.getParticipantBox()); + } + + constraintSet = new ConstraintSet(col, freeX); + constraintSetHBar = new ConstraintSetHBar(col); + + for (Event ev : new ArrayList(drawableSet.getAllEvents())) { + final double diffY = freeY - lastFreeY; + if (autonewpage > 0 && diffY > 0 && diffY + getTotalHeight(0, stringBounder) > autonewpage) { + prepareNewpageSpecial(stringBounder, new Newpage(null), ev); + } + if (ev instanceof MessageExo) { + prepareMessageExo(stringBounder, (MessageExo) ev); + } else if (ev instanceof Message) { + prepareMessage(stringBounder, (Message) ev); + } else if (ev instanceof Note) { + prepareNote(stringBounder, (Note) ev); + } else if (ev instanceof LifeEvent) { + prepareLiveEvent(stringBounder, (LifeEvent) ev); + } else if (ev instanceof GroupingLeaf) { + prepareGroupingLeaf(stringBounder, (GroupingLeaf) ev); + } else if (ev instanceof GroupingStart) { + prepareGroupingStart(stringBounder, (GroupingStart) ev); + } else if (ev instanceof Newpage) { + prepareNewpage(stringBounder, (Newpage) ev); + } else if (ev instanceof Divider) { + prepareDivider(stringBounder, (Divider) ev); + } else { + throw new IllegalStateException(); + } + } + + takeParticipantEngloberTitleWidth(stringBounder); + + constraintSet.takeConstraintIntoAccount(stringBounder); + + prepareMissingSpace(stringBounder); + + final double diagramWidth = constraintSetHBar.takeConstraintIntoAccount(stringBounder, freeX) + 1; + + drawableSet.setDimension(new Dimension2DDouble(diagramWidth, getTotalHeight(freeY, stringBounder))); + return drawableSet; + } + + private void takeParticipantEngloberTitleWidth(StringBounder stringBounder) { + for (ParticipantEnglober pe : drawableSet.getParticipantEnglobers()) { + final double preferredWidth = drawableSet.getEngloberPreferedWidth(stringBounder, pe); + final ParticipantBox first = drawableSet.getLivingParticipantBox(pe.getFirst()).getParticipantBox(); + final ParticipantBox last = drawableSet.getLivingParticipantBox(pe.getLast()).getParticipantBox(); + if (first == last) { + final Constraint constraint1 = constraintSet.getConstraintBefore(first); + final Constraint constraint2 = constraintSet.getConstraintAfter(last); + final double w1 = constraint1.getParticipant1().getPreferredWidth(stringBounder); + final double w2 = constraint2.getParticipant2().getPreferredWidth(stringBounder); + constraint1.ensureValue(preferredWidth / 2 + w1 / 2 + 5); + constraint2.ensureValue(preferredWidth / 2 + w2 / 2 + 5); + } else { + final Pushable beforeFirst = constraintSet.getPrevious(first); + final Pushable afterLast = constraintSet.getNext(last); + // final Constraint constraint1 = + // constraintSet.getConstraint(first, last); + final Constraint constraint1 = constraintSet.getConstraint(beforeFirst, afterLast); + constraint1.ensureValue(preferredWidth + beforeFirst.getPreferredWidth(stringBounder) / 2 + + afterLast.getPreferredWidth(stringBounder) / 2 + 10); + } + // final double x1 = drawableSet.getX1(pe); + // final double x2 = drawableSet.getX2(stringBounder, pe); + // assert x2 > x1; + // final double diff = preferredWidth - (x2 - x1); + // if (diff > 0) { + // } + } + } + + private double getTotalHeight(double y, StringBounder stringBounder) { + final double signature = 0; + return y + drawableSet.getTailHeight(stringBounder, showTail) + signature; + } + + public double getYposition(StringBounder stringBounder, Newpage newpage) { + if (newpage == null) { + throw new IllegalArgumentException(); + } + final GraphicalNewpage graphicalNewpage = (GraphicalNewpage) drawableSet.getEvent(newpage); + return graphicalNewpage.getStartingY(); + } + + private void prepareMissingSpace(StringBounder stringBounder) { + freeX = constraintSet.getMaxX(); + + double missingSpace1 = 0; + double missingSpace2 = 0; + + for (GraphicalElement ev : drawableSet.getAllGraphicalElements()) { + final double startX = ev.getStartingX(stringBounder); + final double delta1 = -startX; + if (delta1 > missingSpace1) { + missingSpace1 = delta1; + } + if (ev instanceof Arrow) { + final Arrow a = (Arrow) ev; + a.setMaxX(freeX); + } + double width = ev.getPreferredWidth(stringBounder); + if (ev instanceof Arrow) { + final Arrow a = (Arrow) ev; + if (width < a.getActualWidth(stringBounder)) { + width = a.getActualWidth(stringBounder); + } + } + final double endX = startX + width; + final double delta2 = endX - freeX; + if (delta2 > missingSpace2) { + missingSpace2 = delta2; + } + } + if (missingSpace1 > 0) { + constraintSet.pushToLeft(missingSpace1); + } + freeX = constraintSet.getMaxX() + missingSpace2; + } + + private void prepareNewpage(StringBounder stringBounder, Newpage newpage) { + final GraphicalNewpage graphicalNewpage = new GraphicalNewpage(freeY, drawableSet.getSkin().createComponent( + ComponentType.NEWPAGE, drawableSet.getSkinParam(), null)); + this.lastFreeY = freeY; + freeY += graphicalNewpage.getPreferredHeight(stringBounder); + drawableSet.addEvent(newpage, graphicalNewpage); + } + + private void prepareNewpageSpecial(StringBounder stringBounder, Newpage newpage, Event justBefore) { + final GraphicalNewpage graphicalNewpage = new GraphicalNewpage(freeY, drawableSet.getSkin().createComponent( + ComponentType.NEWPAGE, drawableSet.getSkinParam(), null)); + this.lastFreeY = freeY; + freeY += graphicalNewpage.getPreferredHeight(stringBounder); + drawableSet.addEvent(newpage, graphicalNewpage, justBefore); + } + + private void prepareDivider(StringBounder stringBounder, Divider divider) { + final GraphicalDivider graphicalDivider = new GraphicalDivider(freeY, drawableSet.getSkin().createComponent( + ComponentType.DIVIDER, drawableSet.getSkinParam(), divider.getText())); + freeY += graphicalDivider.getPreferredHeight(stringBounder); + drawableSet.addEvent(divider, graphicalDivider); + } + + private List inGroupableLists = new ArrayList(); + + private void prepareGroupingStart(StringBounder stringBounder, GroupingStart m) { + if (m.getType() != GroupingType.START) { + throw new IllegalStateException(); + } + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), m.getBackColorElement(), + m.getBackColorGeneral()); + this.maxGrouping++; + final List strings = m.getTitle().equals("group") ? Arrays.asList(m.getComment()) + : Arrays.asList(m.getTitle(), m.getComment()); + final Component header = drawableSet.getSkin().createComponent(ComponentType.GROUPING_HEADER, skinParam, + strings); + final InGroupableList inGroupableList = new InGroupableList(m, freeY); + for (InGroupableList other : inGroupableLists) { + other.addInGroupable(inGroupableList); + } + inGroupableLists.add(inGroupableList); + constraintSetHBar.add(inGroupableList); + + final GraphicalElement element = new GroupingHeader(freeY, header, (m.getLevel() + 1) * groupingMargin, + inGroupableList); + inGroupableList.setMinWidth(element.getPreferredWidth(stringBounder)); + freeY += element.getPreferredHeight(stringBounder); + drawableSet.addEvent(m, element); + } + + private void prepareGroupingLeaf(StringBounder stringBounder, GroupingLeaf m) { + final GraphicalElement element; + if (m.getType() == GroupingType.ELSE) { + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), null, m.getJustBefore() + .getBackColorGeneral()); + final GraphicalElement before = drawableSet.getEvent(m.getJustBefore()); + final Component comp = drawableSet.getSkin().createComponent(ComponentType.GROUPING_ELSE, skinParam, + Arrays.asList(m.getComment())); + final Component body = drawableSet.getSkin().createComponent(ComponentType.GROUPING_BODY, skinParam, null); + double initY = before.getStartingY(); + if (before instanceof GroupingHeader) { + initY += before.getPreferredHeight(stringBounder); + } + element = new GroupingElse(freeY, initY, body, comp, (m.getLevel() + 1) * groupingMargin, + getTopGroupingStructure()); + freeY += element.getPreferredHeight(stringBounder); + } else if (m.getType() == GroupingType.END) { + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), null, m.getJustBefore() + .getBackColorGeneral()); + final GraphicalElement justBefore = drawableSet.getEvent(m.getJustBefore()); + final Component body = drawableSet.getSkin().createComponent(ComponentType.GROUPING_BODY, skinParam, null); + final Component tail = drawableSet.getSkin().createComponent(ComponentType.GROUPING_TAIL, skinParam, null); + double initY = justBefore.getStartingY(); + if (justBefore instanceof GroupingHeader) { + // initY += before.getPreferredHeight(stringBounder); + // A cause de ComponentRoseGroupingHeader::getPaddingY() a + // supprimer + // initY += 7; + initY += tail.getPreferredHeight(stringBounder); + } + element = new GroupingTail(freeY, initY, (m.getLevel() + 1) * groupingMargin, body, tail, + getTopGroupingStructure()); + freeY += tail.getPreferredHeight(stringBounder); + final int idx = inGroupableLists.size() - 1; + inGroupableLists.get(idx).setEndingY(freeY); + inGroupableLists.remove(idx); + } else { + throw new IllegalStateException(); + } + drawableSet.addEvent(m, element); + } + + private void prepareNote(StringBounder stringBounder, Note n) { + LivingParticipantBox p1 = drawableSet.getLivingParticipantBox(n.getParticipant()); + LivingParticipantBox p2; + if (n.getParticipant2() == null) { + p2 = null; + } else { + p2 = drawableSet.getLivingParticipantBox(n.getParticipant2()); + if (p1.getParticipantBox().getCenterX(stringBounder) > p2.getParticipantBox().getCenterX(stringBounder)) { + final LivingParticipantBox tmp = p1; + p1 = p2; + p2 = tmp; + } + } + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), n.getSpecificBackColor()); + final NoteBox noteBox = new NoteBox(freeY, drawableSet.getSkin().createComponent(ComponentType.NOTE, skinParam, + n.getStrings()), p1, p2, n.getPosition()); + + for (InGroupableList groupingStructure : inGroupableLists) { + groupingStructure.addInGroupable(noteBox); + } + + drawableSet.addEvent(n, noteBox); + freeY += noteBox.getPreferredHeight(stringBounder); + } + + private void prepareLiveEvent(StringBounder stringBounder, LifeEvent lifeEvent) { + if (lifeEvent.getType() != LifeEventType.DESTROY && lifeEvent.getType() != LifeEventType.CREATE) { + throw new IllegalStateException(); + } + } + + private void prepareMessage(StringBounder stringBounder, Message m) { + final Step1Message step1Message = new Step1Message(stringBounder, m, drawableSet, freeY); + freeY = step1Message.prepareMessage(constraintSet, inGroupableLists); + } + + private void prepareMessageExo(StringBounder stringBounder, MessageExo m) { + final Step1MessageExo step1Message = new Step1MessageExo(stringBounder, m, drawableSet, freeY); + freeY = step1Message.prepareMessage(constraintSet, inGroupableLists); + } + + private InGroupableList getTopGroupingStructure() { + if (inGroupableLists.size() == 0) { + return null; + } + return inGroupableLists.get(inGroupableLists.size() - 1); + } + + private void prepareParticipant(StringBounder stringBounder, Participant p) { + final ParticipantBox box; + + if (p.getType() == ParticipantType.PARTICIPANT) { + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), p.getSpecificBackColor()); + final Component head = drawableSet.getSkin().createComponent(ComponentType.PARTICIPANT_HEAD, skinParam, + p.getDisplay()); + final Component tail = drawableSet.getSkin().createComponent(ComponentType.PARTICIPANT_TAIL, skinParam, + p.getDisplay()); + final Component line = drawableSet.getSkin().createComponent(ComponentType.PARTICIPANT_LINE, + drawableSet.getSkinParam(), p.getDisplay()); + box = new ParticipantBox(head, line, tail, this.freeX); + } else if (p.getType() == ParticipantType.ACTOR) { + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), p.getSpecificBackColor()); + final Component head = drawableSet.getSkin().createComponent(ComponentType.ACTOR_HEAD, skinParam, + p.getDisplay()); + final Component tail = drawableSet.getSkin().createComponent(ComponentType.ACTOR_TAIL, skinParam, + p.getDisplay()); + final Component line = drawableSet.getSkin().createComponent(ComponentType.ACTOR_LINE, + drawableSet.getSkinParam(), p.getDisplay()); + box = new ParticipantBox(head, line, tail, this.freeX); + } else { + throw new IllegalArgumentException(); + } + + final Component comp = drawableSet.getSkin().createComponent(ComponentType.ALIVE_LINE, + drawableSet.getSkinParam(), null); + + final LifeLine lifeLine = new LifeLine(box, comp.getPreferredWidth(stringBounder)); + drawableSet.addParticipant(p, new LivingParticipantBox(box, lifeLine)); + + this.freeX = box.getMaxX(stringBounder); + } + + public void addParticipant(Participant p) { + drawableSet.addParticipant(p, null); + } + + public void addEvent(Event event) { + drawableSet.addEvent(event, null); + } + + public void addParticipantEnglober(ParticipantEnglober englober) { + drawableSet.addParticipantEnglober(englober); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/FileMaker.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/FileMaker.java new file mode 100644 index 000000000..915d91569 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/FileMaker.java @@ -0,0 +1,50 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5520 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +public interface FileMaker { + + List createMany(final File suggestedFile) throws IOException; + + void createOne(OutputStream os, int index) throws IOException; + + public int getNbPages(); + + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalDivider.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalDivider.java new file mode 100644 index 000000000..036fb29d3 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalDivider.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3916 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class GraphicalDivider extends GraphicalElement { + + private final Component comp; + + public GraphicalDivider(double startingY, Component comp) { + super(startingY); + this.comp = comp; + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + //final double x = ug.getTranslateX(); + ug.translate(0, getStartingY()); + final StringBounder stringBounder = ug.getStringBounder(); + final Dimension2D dim = new Dimension2DDouble(maxX, comp.getPreferredHeight(stringBounder)); + comp.drawU(ug, dim, context); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return comp.getPreferredHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return comp.getPreferredWidth(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalElement.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalElement.java new file mode 100644 index 000000000..29918e290 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalElement.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4696 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +abstract class GraphicalElement { + + private double startingY; + + GraphicalElement(double startingY) { + this.startingY = startingY; + } + + void pushToDown(double delta) { + startingY += delta; + } + + protected final double getStartingY() { + return startingY; + } + + public final void drawU(UGraphic ug, double maxX, Context2D context) { + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + drawInternalU(ug, maxX, context); + ug.setTranslate(atX, atY); + } + + protected abstract void drawInternalU(UGraphic ug, double maxX, Context2D context); + + public abstract double getStartingX(StringBounder stringBounder); + + public abstract double getPreferredWidth(StringBounder stringBounder); + + public abstract double getPreferredHeight(StringBounder stringBounder); + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalNewpage.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalNewpage.java new file mode 100644 index 000000000..37005e378 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GraphicalNewpage.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4696 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class GraphicalNewpage extends GraphicalElement { + + private final Component comp; + + public GraphicalNewpage(double startingY, Component comp) { + super(startingY); + this.comp = comp; + } + + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + //final double x = ug.getTranslateX(); + ug.translate(0, getStartingY()); + final StringBounder stringBounder = ug.getStringBounder(); + final Dimension2D dim = new Dimension2DDouble(maxX, comp.getPreferredHeight(stringBounder)); + comp.drawU(ug, dim, context); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return comp.getPreferredHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return comp.getPreferredWidth(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java new file mode 100644 index 000000000..a0565338f --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java @@ -0,0 +1,103 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4696 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class GroupingElse extends GraphicalElement { + + private final double xpos; + private final Component comp; + private final double initY; + private final Component body; + private final InGroupableList inGroupableList; + + public GroupingElse(double startingY, double initY, Component body, + Component comp, double xpos, InGroupableList inGroupableList) { + super(startingY); + this.xpos = xpos; + this.comp = comp; + this.initY = initY; + this.body = body; + this.inGroupableList = inGroupableList; + if (inGroupableList == null) { + throw new IllegalArgumentException(); + } + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + // final double x1 = inGroupableList.getMinX(stringBounder); + final double x1 = inGroupableList.getBarStart().getCenterX( + stringBounder); + // final double x2 = inGroupableList.getMaxX(stringBounder); + final double x2 = inGroupableList.getBarEnd().getCenterX(stringBounder); + ug.translate(x1, getStartingY()); + + final Dimension2D dim = new Dimension2DDouble(x2 - x1, comp + .getPreferredHeight(stringBounder)); + + final Dimension2D dimBody = new Dimension2DDouble(x2 - x1, + getStartingY() - initY); + comp.drawU(ug, dim, context); + + ug.translate(0, initY - getStartingY()); + + body.drawU(ug, dimBody, context); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return comp.getPreferredHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return comp.getPreferredWidth(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return xpos; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java new file mode 100644 index 000000000..7eea93ca6 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4696 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class GroupingHeader extends GraphicalElement { + + private final Component comp; + private final double xpos; + private final InGroupableList inGroupableList; + + public GroupingHeader(double currentY, Component comp, double xpos, + InGroupableList inGroupableList) { + super(currentY); + this.xpos = xpos; + this.comp = comp; + this.inGroupableList = inGroupableList; + if (inGroupableList == null) { + throw new IllegalArgumentException(); + } + } + + @Override + public String toString() { + return super.toString() + " " + + (inGroupableList == null ? "no" : inGroupableList.toString()); + } + + @Override + final public double getPreferredWidth(StringBounder stringBounder) { + return comp.getPreferredWidth(stringBounder); + } + + @Override + final public double getPreferredHeight(StringBounder stringBounder) { + return comp.getPreferredHeight(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return xpos; + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + // final double x1 = inGroupableList.getMinX(stringBounder); + final double x1 = inGroupableList.getBarStart().getCenterX( + stringBounder); + final double x2 = inGroupableList.getBarEnd().getCenterX(stringBounder); + // final double x2 = inGroupableList.getMaxX(stringBounder); + ug.translate(x1, getStartingY()); + final Dimension2D dim = new Dimension2DDouble(x2 - x1, comp + .getPreferredHeight(stringBounder)); + comp.drawU(ug, dim, context); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java new file mode 100644 index 000000000..c5493d398 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java @@ -0,0 +1,99 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5528 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class GroupingTail extends GraphicalElement { + + private final double initY; + private final double xpos; + private final Component body; + private final Component tail; + private final InGroupableList inGroupableList; + + public GroupingTail(double currentY, double initY, double xpos, Component body, Component tail, + InGroupableList inGroupableList) { + super(currentY); + if (currentY < initY) { + // throw new IllegalArgumentException("currentY=" + currentY + " initY=" + initY); + System.err.println("currentY=" + currentY + " initY=" + initY); + + } + if (inGroupableList == null) { + throw new IllegalArgumentException(); + } + this.body = body; + this.tail = tail; + this.initY = initY; + this.xpos = xpos; + this.inGroupableList = inGroupableList; + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return xpos; + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + // final double x1 = inGroupableList.getMinX(stringBounder); + final double x1 = inGroupableList.getBarStart().getCenterX(stringBounder); + final double x2 = inGroupableList.getBarEnd().getCenterX(stringBounder); + // final double x2 = inGroupableList.getMaxX(stringBounder); + ug.translate(x1, initY); + final Dimension2D dimBody = new Dimension2DDouble(x2 - x1, getPreferredHeight(stringBounder)); + body.drawU(ug, dimBody, context); + tail.drawU(ug, dimBody, context); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getStartingY() - initY; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeDestroy.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeDestroy.java new file mode 100644 index 000000000..c4336e351 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeDestroy.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4696 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class LifeDestroy extends GraphicalElement { + + private final ParticipantBox participant; + + private final Component comp; + + public LifeDestroy(double startingY, ParticipantBox participant, Component comp) { + super(startingY); + this.participant = participant; + this.comp = comp; + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + ug.translate(getStartingX(stringBounder), getStartingY()); + comp.drawU(ug, null, context); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return comp.getPreferredHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return comp.getPreferredWidth(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return participant.getCenterX(stringBounder) - getPreferredWidth(stringBounder) / 2.0; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeLine.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeLine.java new file mode 100644 index 000000000..448949758 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeLine.java @@ -0,0 +1,224 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5275 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class LifeLine { + + static class Variation { + final private LifeSegmentVariation type; + final private HtmlColor backcolor; + final private double y; + + Variation(LifeSegmentVariation type, double y, HtmlColor backcolor) { + this.type = type; + this.y = y; + this.backcolor = backcolor; + } + + @Override + public String toString() { + return type + " " + y; + } + } + + private final Pushable participant; + private final double nominalPreferredWidth; + + private final List events = new ArrayList(); + private int maxLevel = 0; + + public LifeLine(Pushable participant, double nominalPreferredWidth) { + this.participant = participant; + this.nominalPreferredWidth = nominalPreferredWidth; + } + + public void addSegmentVariation(LifeSegmentVariation type, double y, HtmlColor backcolor) { + if (events.size() > 0) { + final Variation last = events.get(events.size() - 1); + if (y < last.y) { + throw new IllegalArgumentException(); + } + if (y==last.y && type != last.type) { + throw new IllegalArgumentException(); + } + } + events.add(new Variation(type, y, backcolor)); + maxLevel = Math.max(getLevel(y), maxLevel); + } + + public void finish(double y) { + final int missingClose = getMissingClose(); + for (int i = 0; i < missingClose; i++) { + addSegmentVariation(LifeSegmentVariation.SMALLER, y, null); + } + } + + int getMissingClose() { + int level = 0; + for (Variation ev : events) { + if (ev.type == LifeSegmentVariation.LARGER) { + level++; + } else { + level--; + } + } + return level; + } + + int getLevel(double y) { + int level = 0; + for (Variation ev : events) { + if (ev.y > y) { + return level; + } + if (ev.type == LifeSegmentVariation.LARGER) { + level++; + } else { + level--; + } + } + return level; + } + + public int getMaxLevel() { + return maxLevel; + } + + public double getRightShift(double y) { + return getRightShiftAtLevel(getLevel(y)); + } + + public double getLeftShift(double y) { + return getLeftShiftAtLevel(getLevel(y)); + } + + public double getMaxRightShift() { + return getRightShiftAtLevel(getMaxLevel()); + } + + public double getMaxLeftShift() { + return getLeftShiftAtLevel(getMaxLevel()); + } + + private double getRightShiftAtLevel(int level) { + if (level == 0) { + return 0; + } + return level * (nominalPreferredWidth / 2.0); + } + + private double getLeftShiftAtLevel(int level) { + if (level == 0) { + return 0; + } + return nominalPreferredWidth / 2.0; + } + + private double getStartingX(StringBounder stringBounder) { + final double delta = participant.getCenterX(stringBounder) - nominalPreferredWidth / 2.0; + return delta; + } + + Collection getSegments() { + final Collection result = new ArrayList(); + for (int i = 0; i < events.size(); i++) { + final Segment seg = getSegment(i); + if (seg != null) { + result.add(seg); + } + } + return result; + } + + private Segment getSegment(int i) { + if (events.get(i).type != LifeSegmentVariation.LARGER) { + return null; + } + int level = 1; + for (int j = i + 1; j < events.size(); j++) { + if (events.get(j).type == LifeSegmentVariation.LARGER) { + level++; + } else { + level--; + } + if (level == 0) { + return new Segment(events.get(i).y, events.get(j).y, events.get(i).backcolor); + } + } + return new Segment(events.get(i).y, events.get(events.size() - 1).y, events.get(i).backcolor); + } + + + public void drawU(UGraphic ug, Skin skin, ISkinParam skinParam) { + final StringBounder stringBounder = ug.getStringBounder(); + + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + + ug.translate(getStartingX(stringBounder), 0); + + for (Segment seg : getSegments()) { + final ISkinParam skinParam2 = new SkinParamBackcolored(skinParam, seg.getSpecificBackColor()); + final Component comp = skin.createComponent(ComponentType.ALIVE_LINE, skinParam2, null); + final int currentLevel = getLevel(seg.getPos1()); + seg.drawU(ug, comp, currentLevel); + } + + ug.setTranslate(atX, atY); + + } + + private double create = 0; + + public final void setCreate(double create) { + this.create = create; + } + + public final double getCreate() { + return create; + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeSegmentVariation.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeSegmentVariation.java new file mode 100644 index 000000000..329d04399 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/LifeSegmentVariation.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +enum LifeSegmentVariation { + LARGER, SMALLER + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java new file mode 100644 index 000000000..a655054a7 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java @@ -0,0 +1,105 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5114 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class LivingParticipantBox implements InGroupable { + + private final ParticipantBox participantBox; + private final LifeLine lifeLine; + + public LivingParticipantBox(ParticipantBox participantBox, LifeLine lifeLine) { + this.participantBox = participantBox; + this.lifeLine = lifeLine; + } + + /** + * @deprecated a virer + */ + public ParticipantBox getParticipantBox() { + return participantBox; + } + + /** + * @deprecated a virer + */ + public LifeLine getLifeLine() { + return lifeLine; + } + + public Segment getLiveThicknessAt(StringBounder stringBounder, double y) { + final double left = lifeLine.getLeftShift(y); + assert left >= 0; + final double right = lifeLine.getRightShift(y); + assert right >= 0; + final double centerX = participantBox.getCenterX(stringBounder); + // System.err.println("Attention, null for segment"); + return new Segment(centerX - left, centerX + right, null); + } + + public void drawLineU(UGraphic ug, double startingY, double endingY, boolean showTail) { + if (endingY <= startingY) { + return; + } + participantBox.drawLineU(ug, startingY, endingY, showTail); + } + + public double magicMargin(StringBounder stringBounder) { + return participantBox.magicMargin(stringBounder); + } + + public void create(double ypos) { + lifeLine.setCreate(ypos); + } + + public double getCreate() { + return lifeLine.getCreate(); + } + + public double getMaxX(StringBounder stringBounder) { + return participantBox.getMaxX(stringBounder); + } + + public double getMinX(StringBounder stringBounder) { + return participantBox.getStartingX(); + } + + public String toString(StringBounder stringBounder) { + return toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java new file mode 100644 index 000000000..c1bf0cdf4 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java @@ -0,0 +1,169 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4855 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.ArrowComponent; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class MessageArrow extends Arrow { + + private final LivingParticipantBox p1; + private final LivingParticipantBox p2; + + public MessageArrow(double startingY, Skin skin, Component arrow, LivingParticipantBox p1, LivingParticipantBox p2) { + super(startingY, skin, arrow); + + if (p1 == p2) { + throw new IllegalArgumentException(); + } + if (p1 == null || p2 == null) { + throw new IllegalArgumentException(); + } + this.p1 = p1; + this.p2 = p2; + } + + @Override + public double getActualWidth(StringBounder stringBounder) { + final double r = getRightEndInternal(stringBounder) - getLeftStartInternal(stringBounder); + assert r > 0; + return r; + } + + private double getLeftStartInternal(StringBounder stringBounder) { + return getParticipantAt(stringBounder, NotePosition.LEFT).getLiveThicknessAt(stringBounder, + getArrowYStartLevel(stringBounder)).getPos2(); + } + + private double getRightEndInternal(StringBounder stringBounder) { + return getParticipantAt(stringBounder, NotePosition.RIGHT).getLiveThicknessAt(stringBounder, + getArrowYStartLevel(stringBounder)).getPos1(); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getArrowComponent().getPreferredHeight(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return getLeftStartInternal(stringBounder); + } + + @Override + public int getDirection(StringBounder stringBounder) { + final double x1 = p1.getParticipantBox().getCenterX(stringBounder); + final double x2 = p2.getParticipantBox().getCenterX(stringBounder); + if (x1 < x2) { + return 1; + } + return -1; + } + + public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position) { + final int direction = getDirection(stringBounder); + if (direction == 1 && position == NotePosition.RIGHT) { + return p2; + } + if (direction == 1 && position == NotePosition.LEFT) { + return p1; + } + if (direction == -1 && position == NotePosition.RIGHT) { + return p1; + } + if (direction == -1 && position == NotePosition.LEFT) { + return p2; + } + throw new IllegalArgumentException(); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getArrowComponent().getPreferredWidth(stringBounder); + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + ug.translate(getStartingX(stringBounder), getStartingY()); + getArrowComponent().drawU(ug, getActualDimension(stringBounder), context); + } + + private Dimension2D getActualDimension(StringBounder stringBounder) { + return new Dimension2DDouble(getActualWidth(stringBounder) - getPaddingArrowHead(), getArrowComponent() + .getPreferredHeight(stringBounder)); + } + + @Override + public double getArrowYStartLevel(StringBounder stringBounder) { + if (getArrowComponent() instanceof ArrowComponent) { + final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), + arrowComponent.getPreferredHeight(stringBounder)); + return getStartingY() + arrowComponent.getStartPoint(stringBounder, dim).getY(); + } + return getStartingY(); + } + + @Override + public double getArrowYEndLevel(StringBounder stringBounder) { + if (getArrowComponent() instanceof ArrowComponent) { + final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), + arrowComponent.getPreferredHeight(stringBounder)); + return getStartingY() + arrowComponent.getEndPoint(stringBounder, dim).getY(); + } + return getStartingY() + getArrowComponent().getPreferredHeight(stringBounder); + } + + public double getMaxX(StringBounder stringBounder) { + return getRightEndInternal(stringBounder); + } + + public double getMinX(StringBounder stringBounder) { + return getLeftStartInternal(stringBounder); + } + + public String toString(StringBounder stringBounder) { + return getMinX(stringBounder) + "-" + getMaxX(stringBounder); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java new file mode 100644 index 000000000..d9aee1514 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java @@ -0,0 +1,163 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4274 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.MessageExoType; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.ArrowComponent; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class MessageExoArrow extends Arrow { + + private final LivingParticipantBox p; + private final MessageExoType type; + + public MessageExoArrow(double startingY, Skin skin, Component arrow, LivingParticipantBox p, MessageExoType type) { + super(startingY, skin, arrow); + + this.p = p; + this.type = type; + } + + double getActualWidth(StringBounder stringBounder, double maxX) { + final double r = getRightEndInternal(stringBounder, maxX) - getLeftStartInternal(stringBounder); + assert r > 0; + return r; + } + + private double getLeftStartInternal(StringBounder stringBounder) { + if (type == MessageExoType.FROM_LEFT || type == MessageExoType.TO_LEFT) { + // return Math.max(0, p.getLiveThicknessAt(stringBounder, + // getArrowYStartLevel(stringBounder)).getPos1() + // - getPreferredWidth(stringBounder)); + return 0; + } + return p.getLiveThicknessAt(stringBounder, getArrowYStartLevel(stringBounder)).getPos2(); + } + + private double getRightEndInternal(StringBounder stringBounder, double maxX) { + if (type == MessageExoType.FROM_LEFT || type == MessageExoType.TO_LEFT) { + return p.getLiveThicknessAt(stringBounder, getArrowYStartLevel(stringBounder)).getPos1(); + } + return Math.max(maxX, getLeftStartInternal(stringBounder) + getPreferredWidth(stringBounder)); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getArrowComponent().getPreferredHeight(stringBounder); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return getLeftStartInternal(stringBounder); + } + + @Override + public int getDirection(StringBounder stringBounder) { + return type.getDirection(); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getArrowComponent().getPreferredWidth(stringBounder); + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + ug.translate(getStartingX(stringBounder), getStartingY()); + getArrowComponent().drawU(ug, getActualDimension(stringBounder, maxX), context); + } + + private Dimension2D getActualDimension(StringBounder stringBounder, double maxX) { + return new Dimension2DDouble(getActualWidth(stringBounder, maxX), getArrowComponent().getPreferredHeight( + stringBounder)); + } + + @Override + public double getArrowYStartLevel(StringBounder stringBounder) { + if (getArrowComponent() instanceof ArrowComponent) { + final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), + arrowComponent.getPreferredHeight(stringBounder)); + return getStartingY() + arrowComponent.getStartPoint(stringBounder, dim).getY(); + } + return getStartingY(); + } + + @Override + public double getArrowYEndLevel(StringBounder stringBounder) { + if (getArrowComponent() instanceof ArrowComponent) { + final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), + arrowComponent.getPreferredHeight(stringBounder)); + return getStartingY() + arrowComponent.getEndPoint(stringBounder, dim).getY(); + } + return getStartingY() + getArrowComponent().getPreferredHeight(stringBounder); + } + + public double getMaxX(StringBounder stringBounder) { + return getRightEndInternal(stringBounder, 0); + } + + public double getMinX(StringBounder stringBounder) { + return getLeftStartInternal(stringBounder); + } + + public String toString(StringBounder stringBounder) { + return getMinX(stringBounder) + "-" + getMaxX(stringBounder); + } + + public final MessageExoType getType() { + return type; + } + + @Override + public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position) { + return p; + } + + @Override + public double getActualWidth(StringBounder stringBounder) { + return getActualWidth(stringBounder, getMaxX()); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java new file mode 100644 index 000000000..fc50c441d --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4855 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.ArrowComponent; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class MessageSelfArrow extends Arrow { + + private final LivingParticipantBox p1; + + public MessageSelfArrow(double startingY, Skin skin, Component arrow, LivingParticipantBox p1) { + super(startingY, skin, arrow); + this.p1 = p1; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getArrowComponent().getPreferredHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getArrowComponent().getPreferredWidth(stringBounder); + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + ug.translate(getStartingX(stringBounder), getStartingY()); + getArrowComponent().drawU(ug, + new Dimension2DDouble(getPreferredWidth(stringBounder), getPreferredHeight(stringBounder)), context); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + return p1.getLiveThicknessAt(stringBounder, getArrowYStartLevel(stringBounder)).getPos2(); + } + + @Override + public int getDirection(StringBounder stringBounder) { + return 1; + } + + @Override + public double getArrowYStartLevel(StringBounder stringBounder) { + if (getArrowComponent() instanceof ArrowComponent) { + final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), + arrowComponent.getPreferredHeight(stringBounder)); + return getStartingY() + arrowComponent.getStartPoint(stringBounder, dim).getY(); + } + return getStartingY(); + } + + @Override + public double getArrowYEndLevel(StringBounder stringBounder) { + if (getArrowComponent() instanceof ArrowComponent) { + final ArrowComponent arrowComponent = (ArrowComponent) getArrowComponent(); + final Dimension2D dim = new Dimension2DDouble(arrowComponent.getPreferredWidth(stringBounder), + arrowComponent.getPreferredHeight(stringBounder)); + return getStartingY() + arrowComponent.getEndPoint(stringBounder, dim).getY(); + } + return getStartingY() + getArrowComponent().getPreferredHeight(stringBounder); + } + + public double getMaxX(StringBounder stringBounder) { + return getStartingX(stringBounder) + getPreferredWidth(stringBounder); + } + + public double getMinX(StringBounder stringBounder) { + return getStartingX(stringBounder); + } + + public String toString(StringBounder stringBounder) { + return super.toString(); + } + + @Override + public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position) { + return p1; + } + + @Override + public double getActualWidth(StringBounder stringBounder) { + return getPreferredWidth(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java new file mode 100644 index 000000000..89bc2f4a1 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java @@ -0,0 +1,138 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4696 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class NoteBox extends GraphicalElement implements InGroupable { + + private final NotePosition position; + + private final LivingParticipantBox p1; + private final LivingParticipantBox p2; + + private final Component comp; + + private double delta = 0; + + public NoteBox(double startingY, Component comp, LivingParticipantBox p1, LivingParticipantBox p2, + NotePosition position) { + super(startingY); + if (p1 == null) { + throw new IllegalArgumentException(); + } + if (p2 != null ^ position == NotePosition.OVER_SEVERAL) { + throw new IllegalArgumentException(); + } + this.p1 = p1; + this.p2 = p2; + this.position = position; + this.comp = comp; + } + + @Override + final public double getPreferredWidth(StringBounder stringBounder) { + return comp.getPreferredWidth(stringBounder); + } + + @Override + final public double getPreferredHeight(StringBounder stringBounder) { + return comp.getPreferredHeight(stringBounder); + } + + @Override + protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { + final StringBounder stringBounder = ug.getStringBounder(); + final double xStart = getStartingX(stringBounder); + ug.translate(xStart, getStartingY()); + final Dimension2D dimensionToUse = new Dimension2DDouble(comp.getPreferredWidth(stringBounder), comp + .getPreferredHeight(stringBounder)); + comp.drawU(ug, dimensionToUse, context); + } + + @Override + public double getStartingX(StringBounder stringBounder) { + final Segment segment = getSegment(stringBounder); + final int xStart; + if (position == NotePosition.LEFT) { + xStart = (int) (segment.getPos1() - getPreferredWidth(stringBounder)); + } else if (position == NotePosition.RIGHT) { + xStart = (int) (segment.getPos2()); + } else if (position == NotePosition.OVER) { + xStart = (int) (p1.getParticipantBox().getCenterX(stringBounder) - getPreferredWidth(stringBounder) / 2); + } else if (position == NotePosition.OVER_SEVERAL) { + final double centre = (p1.getParticipantBox().getCenterX(stringBounder) + p2.getParticipantBox() + .getCenterX(stringBounder)) / 2.0; + xStart = (int) (centre - getPreferredWidth(stringBounder) / 2.0); + } else { + throw new IllegalStateException(); + } +// if (InGroupableList.NEW_METHOD) { +// System.err.println("GET STARTING X OF " + this + " " + (xStart + delta)); +// } + return xStart + delta; + } + + private Segment getSegment(StringBounder stringBounder) { + final Segment segment = p1.getLiveThicknessAt(stringBounder, getStartingY()); + final Segment segment2 = p1.getLiveThicknessAt(stringBounder, getStartingY() + + comp.getPreferredHeight(stringBounder)); + return segment.merge(segment2); + } + + public void pushToRight(double x) { + this.delta += x; + } + + public double getMaxX(StringBounder stringBounder) { + return getStartingX(stringBounder) + getPreferredWidth(stringBounder); + } + + public double getMinX(StringBounder stringBounder) { + return getStartingX(stringBounder); + } + + public String toString(StringBounder stringBounder) { + return toString(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Page.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Page.java new file mode 100644 index 000000000..5d28dee5b --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Page.java @@ -0,0 +1,121 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4822 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.List; + +public final class Page { + + private final double headerHeight; + private final double newpage1; + private final double newpage2; + private final double tailHeight; + private final double signatureHeight; + private final List title; + + @Override + public String toString() { + return "headerHeight=" + headerHeight + " newpage1=" + newpage1 + " newpage2=" + newpage2; + } + + public Page(double headerHeight, double newpage1, double newpage2, double tailHeight, + double signatureHeight, List title) { + if (headerHeight < 0) { + throw new IllegalArgumentException(); + } + if (tailHeight < 0) { + throw new IllegalArgumentException(); + } + if (signatureHeight < 0) { + throw new IllegalArgumentException(); + } + if (newpage1 > newpage2) { + throw new IllegalArgumentException(); + } + this.headerHeight = headerHeight; + this.newpage1 = newpage1; + this.newpage2 = newpage2; + this.tailHeight = tailHeight; + this.signatureHeight = signatureHeight; + this.title = title; + } + + public double getHeight() { + return headerHeight + getBodyHeight() + tailHeight + signatureHeight; + } + + public double getHeaderRelativePosition() { + return 0; + } + + public double getBodyRelativePosition() { + return getHeaderRelativePosition() + headerHeight; + } + + public double getBodyHeight() { + return newpage2 - newpage1; + } + + public double getTailRelativePosition() { + return getBodyRelativePosition() + getBodyHeight(); + } + + public double getSignatureRelativePosition() { + if (displaySignature() == false) { + return -1; + } + return getTailRelativePosition() + tailHeight; + } + + public boolean displaySignature() { + return signatureHeight > 0; + } + + public double getNewpage1() { + return newpage1; + } + + public double getNewpage2() { + return newpage2; + } + + public double getHeaderHeight() { + return headerHeight; + } + + public final List getTitle() { + return title; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/PageSplitter.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/PageSplitter.java new file mode 100644 index 000000000..2345789f0 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/PageSplitter.java @@ -0,0 +1,114 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4935 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.sequencediagram.Newpage; + +class PageSplitter { + + private final double fullHeight; + private final List positions; + private final List> titles; + private final double headerHeight; + private final double tailHeight; + private final double signatureHeight; + private final double newpageHeight; + private final List diagramTitle; + + PageSplitter(double fullHeight, double headerHeight, Map newpages, double tailHeight, + double signatureHeight, double newpageHeight, List diagramTitle) { + this.fullHeight = fullHeight; + this.diagramTitle = diagramTitle; + this.titles = new ArrayList>(); + this.positions = new ArrayList(); + + for (Map.Entry ent : newpages.entrySet()) { + titles.add(ent.getKey().getTitle()); + positions.add(ent.getValue()); + } + + this.headerHeight = headerHeight; + this.tailHeight = tailHeight; + this.signatureHeight = signatureHeight; + this.newpageHeight = newpageHeight; + } + + public List getPages() { + + if (positions.size() == 0) { + return Arrays.asList(onePage()); + } + final List result = new ArrayList(); + + result.add(firstPage()); + for (int i = 0; i < positions.size() - 1; i++) { + result.add(createPage(i)); + } + result.add(lastPage()); + + return result; + } + + private Page lastPage() { + final double newpage1 = positions.get(positions.size() - 1) - this.newpageHeight; + final double newpage2 = this.fullHeight - this.tailHeight - this.signatureHeight; + final List title = titles.get(positions.size() - 1); + return new Page(headerHeight, newpage1, newpage2, tailHeight, signatureHeight, title); + } + + private Page firstPage() { + final double newpage1 = this.headerHeight; + final double newpage2 = positions.get(0) + this.newpageHeight; + return new Page(headerHeight, newpage1, newpage2, tailHeight, 0, diagramTitle); + } + + private Page onePage() { + final double newpage1 = this.headerHeight; + final double newpage2 = this.fullHeight - this.tailHeight - this.signatureHeight; + return new Page(headerHeight, newpage1, newpage2, tailHeight, signatureHeight, diagramTitle); + } + + private Page createPage(int i) { + final double newpage1 = positions.get(i) - this.newpageHeight; + final double newpage2 = positions.get(i + 1) + this.newpageHeight; + final List title = titles.get(i); + return new Page(headerHeight, newpage1, newpage2, tailHeight, 0, title); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ParticipantBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ParticipantBox.java new file mode 100644 index 000000000..d0c7e902c --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ParticipantBox.java @@ -0,0 +1,151 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5249 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ParticipantBox implements Pushable { + + private static int CPT = 0; + + private final int outMargin = 5; + + private double startingX; + + private final Component head; + private final Component line; + private final Component tail; + private int cpt = CPT++; + + public ParticipantBox(Component head, Component line, Component tail, double startingX) { + this.startingX = startingX; + this.head = head; + this.line = line; + this.tail = tail; + } + + @Override + public String toString() { + return "PB" + cpt; + } + + public double getMaxX(StringBounder stringBounder) { + return startingX + head.getPreferredWidth(stringBounder) + 2 * outMargin; + } + + public double getCenterX(StringBounder stringBounder) { + return startingX + head.getPreferredWidth(stringBounder) / 2.0 + outMargin; + } + + public double getHeadHeight(StringBounder stringBounder) { + return head.getPreferredHeight(stringBounder) + line.getPreferredHeight(stringBounder) / 2.0; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return head.getPreferredWidth(stringBounder); + } + + public double getTailHeight(StringBounder stringBounder) { + return tail.getPreferredHeight(stringBounder) + line.getPreferredHeight(stringBounder) / 2.0; + } + + public void pushToLeft(double deltaX) { + startingX += deltaX; + } + + public void drawHeadTailU(UGraphic ug, double topStartingY, boolean showHead, double positionTail) { + if (topStartingY == 0) { + throw new IllegalStateException("setTopStartingY cannot be zero"); + } + + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + final StringBounder stringBounder = ug.getStringBounder(); + + if (showHead) { + final double y1 = topStartingY - head.getPreferredHeight(stringBounder) + - line.getPreferredHeight(stringBounder) / 2; + ug.translate(startingX + outMargin, y1); + head.drawU(ug, new Dimension2DDouble(head.getPreferredWidth(stringBounder), head + .getPreferredHeight(stringBounder)), new SimpleContext2D(false)); + ug.setTranslate(atX, atY); + } + + if (positionTail > 0) { + // final double y2 = positionTail - topStartingY + line.getPreferredHeight(stringBounder) / 2 - 1; + positionTail += line.getPreferredHeight(stringBounder) / 2 - 1; +// if (y2 != y22) { +// throw new IllegalStateException(); +// } + ug.translate(startingX + outMargin, positionTail); + tail.drawU(ug, new Dimension2DDouble(tail.getPreferredWidth(stringBounder), tail + .getPreferredHeight(stringBounder)), new SimpleContext2D(false)); + ug.setTranslate(atX, atY); + } + } + + public void drawParticipantHead(UGraphic ug) { + ug.translate(outMargin, 0); + final StringBounder stringBounder = ug.getStringBounder(); + head.drawU(ug, new Dimension2DDouble(head.getPreferredWidth(stringBounder), head + .getPreferredHeight(stringBounder)), new SimpleContext2D(false)); + ug.translate(-outMargin, 0); + } + + public void drawLineU(UGraphic ug, double startingY, double endingY, boolean showTail) { + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + final StringBounder stringBounder = ug.getStringBounder(); + + ug.translate(startingX, startingY); + line.drawU(ug, + new Dimension2DDouble(head.getPreferredWidth(stringBounder) + outMargin * 2, endingY - startingY), + new SimpleContext2D(false)); + + ug.setTranslate(atX, atY); + } + + public double magicMargin(StringBounder stringBounder) { + return line.getPreferredHeight(stringBounder) / 2; + } + + public double getStartingX() { + return startingX; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ParticipantBoxSimple.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ParticipantBoxSimple.java new file mode 100644 index 000000000..593c4e60b --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ParticipantBoxSimple.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5249 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; + +class ParticipantBoxSimple implements Pushable { + + private double pos = 0; + private final String name; + + public ParticipantBoxSimple(double pos) { + this(pos, null); + } + + public ParticipantBoxSimple(double pos, String name) { + this.pos = pos; + this.name = name; + } + + @Override + public String toString() { + return name == null ? super.toString() : name; + } + + public double getCenterX(StringBounder stringBounder) { + return pos; + } + + public void pushToLeft(double deltaX) { + pos += deltaX; + } + + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Pushable.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Pushable.java new file mode 100644 index 000000000..c06c7d63c --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Pushable.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5249 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; + +interface Pushable { + + double getPreferredWidth(StringBounder stringBounder); + + double getCenterX(StringBounder stringBounder); + + void pushToLeft(double deltaX); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java new file mode 100644 index 000000000..1b1595012 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java @@ -0,0 +1,111 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4699 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +class Segment { + + final private double pos1; + final private double pos2; + final private HtmlColor backcolor; + + Segment(double pos1, double pos2, HtmlColor backcolor) { + this.pos1 = pos1; + this.pos2 = pos2; + this.backcolor = backcolor; + if (pos2 < pos1) { + throw new IllegalArgumentException("pos1=" + pos1 + " pos2=" + pos2); + } + } + + public HtmlColor getSpecificBackColor() { + return backcolor; + } + + @Override + public boolean equals(Object obj) { + final Segment this2 = (Segment) obj; + return pos1 == this2.pos1 && pos2 == this2.pos2; + } + + @Override + public int hashCode() { + return new Double(pos1).hashCode() + new Double(pos2).hashCode(); + } + + public boolean contains(double y) { + return y >= pos1 && y <= pos2; + } + + @Override + public String toString() { + return "" + pos1 + " - " + pos2; + } + + public void drawU(UGraphic ug, Component comp, int level) { + final double atX = ug.getTranslateX(); + final double atY = ug.getTranslateY(); + + final StringBounder stringBounder = ug.getStringBounder(); + ug.translate((level - 1) * comp.getPreferredWidth(stringBounder) / 2, pos1); + final Dimension2D dim = new Dimension2DDouble(comp.getPreferredWidth(stringBounder), pos2 - pos1); + comp.drawU(ug, dim, new SimpleContext2D(false)); + ug.setTranslate(atX, atY); + } + + public double getLength() { + return pos2 - pos1; + } + + public double getPos1() { + return pos1; + } + + public double getPos2() { + return pos2; + } + + public Segment merge(Segment this2) { + return new Segment(Math.min(this.pos1, this2.pos1), Math.max(this.pos2, this2.pos2), backcolor); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramArea.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramArea.java new file mode 100644 index 000000000..a47dab1d7 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramArea.java @@ -0,0 +1,144 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; + +public class SequenceDiagramArea { + + private final double sequenceWidth; + private final double sequenceHeight; + + private double headerWidth; + private double headerHeight; + private double headerMargin; + + private double titleWidth; + private double titleHeight; + + private double footerWidth; + private double footerHeight; + private double footerMargin; + + public SequenceDiagramArea(double width, double height) { + this.sequenceWidth = width; + this.sequenceHeight = height; + } + + public void setTitleArea(double titleWidth, double titleHeight) { + this.titleWidth = titleWidth; + this.titleHeight = titleHeight; + } + + public void setHeaderArea(double headerWidth, double headerHeight, double headerMargin) { + this.headerWidth = headerWidth; + this.headerHeight = headerHeight; + this.headerMargin = headerMargin; + } + + public void setFooterArea(double footerWidth, double footerHeight, double footerMargin) { + this.footerWidth = footerWidth; + this.footerHeight = footerHeight; + this.footerMargin = footerMargin; + } + + public double getWidth() { + double result = sequenceWidth; + if (headerWidth > result) { + result = headerWidth; + } + if (titleWidth > result) { + result = titleWidth; + } + if (footerWidth > result) { + result = footerWidth; + } + return result; + } + + public double getHeight() { + return sequenceHeight + headerHeight + headerMargin + titleHeight + footerMargin + footerHeight; + } + + public double getTitleX() { + return (getWidth() - titleWidth) / 2; + } + + public double getTitleY() { + return headerHeight + headerMargin; + } + + public double getSequenceAreaX() { + return (getWidth() - sequenceWidth) / 2; + } + + public double getSequenceAreaY() { + return getTitleY() + titleHeight; + } + + public double getHeaderY() { + return 0; + } + + public double getFooterY() { + return sequenceHeight + headerHeight + headerMargin + titleHeight + footerMargin; + } + + public double getFooterX(HorizontalAlignement align) { + if (align == HorizontalAlignement.LEFT) { + return 0; + } + if (align == HorizontalAlignement.RIGHT) { + return getWidth() - footerWidth; + } + if (align == HorizontalAlignement.CENTER) { + return (getWidth() - footerWidth) / 2; + } + throw new IllegalStateException(); + } + + public double getHeaderX(HorizontalAlignement align) { + if (align == HorizontalAlignement.LEFT) { + return 0; + } + if (align == HorizontalAlignement.RIGHT) { + return getWidth() - headerWidth; + } + if (align == HorizontalAlignement.CENTER) { + return (getWidth() - headerWidth) / 2; + } + throw new IllegalStateException(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java new file mode 100644 index 000000000..8419b3a44 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java @@ -0,0 +1,406 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5520 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.eps.EpsStrategy; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.VerticalPosition; +import net.sourceforge.plantuml.png.PngIO; +import net.sourceforge.plantuml.png.PngTitler; +import net.sourceforge.plantuml.sequencediagram.Event; +import net.sourceforge.plantuml.sequencediagram.LifeEvent; +import net.sourceforge.plantuml.sequencediagram.LifeEventType; +import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.Newpage; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; +import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; +import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; + +public class SequenceDiagramFileMaker implements FileMaker { + + private static final StringBounder dummyStringBounder; + + static { + final BufferedImage imDummy = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); + dummyStringBounder = StringBounderUtils.asStringBounder(imDummy.createGraphics()); + } + + private final SequenceDiagram diagram; + private final DrawableSet drawableSet; + private final Dimension2D fullDimension; + private final List pages; + private final FileFormat fileFormat; + + public SequenceDiagramFileMaker(SequenceDiagram sequenceDiagram, Skin skin, FileFormat fileFormat) { + HtmlColor.setForceMonochrome(sequenceDiagram.getSkinParam().isMonochrome()); + this.diagram = sequenceDiagram; + this.fileFormat = fileFormat; + final DrawableSetInitializer initializer = new DrawableSetInitializer(skin, sequenceDiagram.getSkinParam(), + sequenceDiagram.isShowFootbox(), sequenceDiagram.getAutonewpage()); + + for (Participant p : sequenceDiagram.participants().values()) { + initializer.addParticipant(p); + } + for (ParticipantEnglober englober : sequenceDiagram.getParticipantEnglobers()) { + initializer.addParticipantEnglober(englober); + } + + for (Event ev : sequenceDiagram.events()) { + initializer.addEvent(ev); + if (ev instanceof Message) { + // TODO mieux faire + final Message m = (Message) ev; + for (LifeEvent lifeEvent : m.getLiveEvents()) { + if (lifeEvent.getType() == LifeEventType.DESTROY + /* + * || lifeEvent.getType() == LifeEventType.CREATE + */) { + initializer.addEvent(lifeEvent); + } + } + } + } + drawableSet = initializer.createDrawableSet(dummyStringBounder); + final List newpages = new ArrayList(); + for (Event ev : drawableSet.getAllEvents()) { + if (ev instanceof Newpage) { + newpages.add((Newpage) ev); + } + } + fullDimension = drawableSet.getDimension(); + final Map positions = new LinkedHashMap(); + for (Newpage n : newpages) { + positions.put(n, initializer.getYposition(dummyStringBounder, n)); + } + pages = create(drawableSet, positions, sequenceDiagram.isShowFootbox(), sequenceDiagram.getTitle()).getPages(); + } + + public int getNbPages() { + return pages.size(); + } + + private PageSplitter create(DrawableSet drawableSet, Map positions, boolean showFootbox, + List title) { + + final double headerHeight = drawableSet.getHeadHeight(dummyStringBounder); + final double tailHeight = drawableSet.getTailHeight(dummyStringBounder, showFootbox); + final double signatureHeight = 0; + final double newpageHeight = drawableSet.getSkin().createComponent(ComponentType.NEWPAGE, + drawableSet.getSkinParam(), Arrays.asList("")).getPreferredHeight(dummyStringBounder); + + return new PageSplitter(fullDimension.getHeight(), headerHeight, positions, tailHeight, signatureHeight, + newpageHeight, title); + } + + public List createMany(final File suggestedFile) throws IOException { + final List result = new ArrayList(); + if (fileFormat == FileFormat.ATXT) { + throw new UnsupportedOperationException(); + } + for (int i = 0; i < pages.size(); i++) { + final UGraphic createImage = createImage((int) fullDimension.getWidth(), pages.get(i), i); + final File f = computeFilename(suggestedFile, i, fileFormat); + Log.info("Creating file: " + f); + if (createImage instanceof UGraphicG2d) { + final BufferedImage im = ((UGraphicG2d) createImage).getBufferedImage(); + Log.info("Image size " + im.getWidth() + " x " + im.getHeight()); + PngIO.write(im, f, diagram.getMetadata()); + } else if (createImage instanceof UGraphicSvg && fileFormat == FileFormat.SVG) { + final UGraphicSvg svg = (UGraphicSvg) createImage; + final FileOutputStream fos = new FileOutputStream(f); + try { + svg.createXml(fos); + } finally { + fos.close(); + } + // } else if (createImage instanceof UGraphicSvg && fileFormat + // == FileFormat.EPS_VIA_SVG) { + // final File svgFile = + // CucaDiagramFileMaker.createTempFile("seq", ".svg"); + // final UGraphicSvg svg = (UGraphicSvg) createImage; + // final FileOutputStream fos = new FileOutputStream(svgFile); + // try { + // svg.createXml(fos); + // } finally { + // fos.close(); + // } + // try { + // InkscapeUtils.create().createEps(svgFile, f); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // Log.error("Error "+e); + // throw new IOException(e.toString()); + // } + } else if (createImage instanceof UGraphicEps) { + final UGraphicEps eps = (UGraphicEps) createImage; + final FileWriter fw = new FileWriter(f); + try { + fw.write(eps.getEPSCode()); + } finally { + fw.close(); + } + } else { + throw new IllegalStateException(); + } + Log.info("File size : " + f.length()); + result.add(f); + } + return result; + } + + public void createOne(OutputStream os, int index) throws IOException { + final UGraphic createImage = createImage((int) fullDimension.getWidth(), pages.get(index), index); + if (createImage instanceof UGraphicG2d) { + final BufferedImage im = ((UGraphicG2d) createImage).getBufferedImage(); + PngIO.write(im, os, diagram.getMetadata()); + } else if (createImage instanceof UGraphicSvg) { + final UGraphicSvg svg = (UGraphicSvg) createImage; + svg.createXml(os); + } else if (createImage instanceof UGraphicEps) { + final UGraphicEps eps = (UGraphicEps) createImage; + os.write(eps.getEPSCode().getBytes()); + } + } + + private double getImageWidth(SequenceDiagramArea area, boolean rotate) { + final int minsize = diagram.getMinwidth(); + final double w = getImageWidthWithoutMinsize(area, rotate); + if (minsize == Integer.MAX_VALUE) { + return w; + } + if (w >= minsize) { + return w; + } + return minsize; + } + + private double getScale(double width, double height) { + if (diagram.getScale()==null) { + return 1; + } + return diagram.getScale().getScale(width, height); + } + + private double getImageWidthWithoutMinsize(SequenceDiagramArea area, boolean rotate) { + final double w; + if (rotate) { + w = area.getHeight() * getScale(area.getWidth(), area.getHeight()); + } else { + w = area.getWidth() * getScale(area.getWidth(), area.getHeight()); + } + return w; + } + + private double getImageHeight(SequenceDiagramArea area, final Page page, boolean rotate) { + if (rotate) { + return area.getWidth() * getScale(area.getWidth(), area.getHeight()); + } + return area.getHeight() * getScale(area.getWidth(), area.getHeight()); + } + + private UGraphic createImage(final int diagramWidth, final Page page, final int indice) { + double delta = 0; + if (indice > 0) { + delta = page.getNewpage1() - page.getHeaderHeight(); + } + if (delta < 0) { + throw new IllegalArgumentException(); + } + + final SequenceDiagramArea area = new SequenceDiagramArea(diagramWidth, page.getHeight()); + + Component compTitle = null; + + if (page.getTitle() != null) { + compTitle = drawableSet.getSkin().createComponent(ComponentType.TITLE, drawableSet.getSkinParam(), + page.getTitle()); + area.setTitleArea(compTitle.getPreferredWidth(dummyStringBounder), compTitle + .getPreferredHeight(dummyStringBounder)); + } + addFooter2(area); + addHeader2(area); + + final Color backColor = diagram.getSkinParam().getBackgroundColor().getColor(); + final UGraphic ug; + final double imageWidth = getImageWidth(area, diagram.isRotation()); + if (fileFormat == FileFormat.PNG) { + double imageHeight = getImageHeight(area, page, diagram.isRotation()); + if (imageHeight == 0) { + imageHeight = 1; + } + final EmptyImageBuilder builder = new EmptyImageBuilder((int) imageWidth, (int) imageHeight, backColor); + + final Graphics2D graphics2D = builder.getGraphics2D(); + if (diagram.isRotation()) { + final AffineTransform at = new AffineTransform(0, 1, 1, 0, 0, 0); + at.concatenate(new AffineTransform(-1, 0, 0, 1, imageHeight, 0)); + at.concatenate(AffineTransform.getTranslateInstance(0.01, 0)); + graphics2D.setTransform(at); + } + final AffineTransform scale = graphics2D.getTransform(); + scale.scale(getScale(area.getWidth(), area.getHeight()), getScale(area.getWidth(), area.getHeight())); + graphics2D.setTransform(scale); + ug = new UGraphicG2d(graphics2D, builder.getBufferedImage()); + } else if (fileFormat == FileFormat.SVG) { + if (backColor.equals(Color.WHITE)) { + ug = new UGraphicSvg(false); + } else { + ug = new UGraphicSvg(HtmlColor.getAsHtml(backColor), false); + } + } else if (fileFormat == FileFormat.EPS) { + ug = new UGraphicEps(EpsStrategy.getDefault()); + } else { + throw new UnsupportedOperationException(); + } + + final int diff = (int) Math.round((imageWidth - getImageWidthWithoutMinsize(area, diagram.isRotation())) / 2); + if (diagram.isRotation()) { + ug.translate(0, diff); + } else { + ug.translate(diff, 0); + } + + if (compTitle != null) { + ug.translate(area.getTitleX(), area.getTitleY()); + final StringBounder stringBounder = ug.getStringBounder(); + final double h = compTitle.getPreferredHeight(stringBounder); + final double w = compTitle.getPreferredWidth(stringBounder); + compTitle.drawU(ug, new Dimension2DDouble(w, h), new SimpleContext2D(false)); + ug.translate(-area.getTitleX(), -area.getTitleY()); + } + + addHeader3(area, ug); + addFooter3(area, ug); + + ug.translate(area.getSequenceAreaX(), area.getSequenceAreaY()); + drawableSet.drawU(ug, delta, diagramWidth, page, diagram.isShowFootbox()); + + return ug; + } + + static public File computeFilename(File pngFile, int i, FileFormat fileFormat) { + if (i == 0) { + return pngFile; + } + final File dir = pngFile.getParentFile(); + String name = pngFile.getName(); + name = name.replaceAll("\\" + fileFormat.getFileSuffix() + "$", "_" + String.format("%03d", i) + + fileFormat.getFileSuffix()); + return new File(dir, name); + + } + + private void addFooter2(SequenceDiagramArea area) { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.FOOTER); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.FOOTER); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, diagram + .getFooterAlignement(), VerticalPosition.BOTTOM); + final Dimension2D dim = pngTitler.getTextDimension(dummyStringBounder); + if (dim != null) { + area.setFooterArea(dim.getWidth(), dim.getHeight(), 3); + } + } + + private void addHeader2(SequenceDiagramArea area) { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.HEADER); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.HEADER); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, diagram + .getHeaderAlignement(), VerticalPosition.TOP); + final Dimension2D dim = pngTitler.getTextDimension(dummyStringBounder); + if (dim != null) { + area.setHeaderArea(dim.getWidth(), dim.getHeight(), 3); + } + } + + private void addFooter3(SequenceDiagramArea area, UGraphic ug) { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.FOOTER); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.FOOTER); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, diagram + .getFooterAlignement(), VerticalPosition.BOTTOM); + final TextBlock text = pngTitler.getTextBlock(); + if (text == null) { + return; + } + text.drawU(ug, area.getFooterX(diagram.getFooterAlignement()), area.getFooterY()); + } + + private void addHeader3(SequenceDiagramArea area, UGraphic ug) { + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.HEADER); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.HEADER); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, diagram + .getHeaderAlignement(), VerticalPosition.TOP); + final TextBlock text = pngTitler.getTextBlock(); + if (text == null) { + return; + } + text.drawU(ug, area.getHeaderX(diagram.getHeaderAlignement()), area.getHeaderY()); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java new file mode 100644 index 000000000..292dbd5e0 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java @@ -0,0 +1,125 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4935 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.awt.geom.Dimension2D; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.asciiart.TextSkin; +import net.sourceforge.plantuml.asciiart.TextStringBounder; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.Event; +import net.sourceforge.plantuml.sequencediagram.LifeEvent; +import net.sourceforge.plantuml.sequencediagram.LifeEventType; +import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; + +public class SequenceDiagramTxtMaker implements FileMaker { + + private final SequenceDiagram diagram; + private final DrawableSet drawableSet; + private final Dimension2D fullDimension; + private final StringBounder dummyStringBounder = new TextStringBounder(); + private final UGraphicTxt ug = new UGraphicTxt(); + private final FileFormat fileFormat; + private final Skin skin; + + public SequenceDiagramTxtMaker(SequenceDiagram sequenceDiagram, FileFormat fileFormat) { + this.fileFormat = fileFormat; + this.diagram = sequenceDiagram; + this.skin = new TextSkin(fileFormat); + + final DrawableSetInitializer initializer = new DrawableSetInitializer(skin, sequenceDiagram.getSkinParam(), + sequenceDiagram.isShowFootbox(), sequenceDiagram.getAutonewpage()); + + for (Participant p : sequenceDiagram.participants().values()) { + initializer.addParticipant(p); + } + for (Event ev : sequenceDiagram.events()) { + initializer.addEvent(ev); + if (ev instanceof Message) { + // TODO mieux faire + final Message m = (Message) ev; + for (LifeEvent lifeEvent : m.getLiveEvents()) { + if (lifeEvent.getType() == LifeEventType.DESTROY + /* + * || lifeEvent.getType() == LifeEventType.CREATE + */) { + initializer.addEvent(lifeEvent); + } + } + } + } + drawableSet = initializer.createDrawableSet(dummyStringBounder); + // final List newpages = new ArrayList(); + // for (Event ev : drawableSet.getAllEvents()) { + // if (ev instanceof Newpage) { + // newpages.add((Newpage) ev); + // } + // } + fullDimension = drawableSet.getDimension(); + final double headerHeight = drawableSet.getHeadHeight(dummyStringBounder); + final double tailHeight = drawableSet.getTailHeight(dummyStringBounder, diagram.isShowFootbox()); + final double newpage2 = fullDimension.getHeight() - (diagram.isShowFootbox() ? tailHeight : 0) - headerHeight; + final Page page = new Page(headerHeight, 0, newpage2, tailHeight, 0, null); + drawableSet.drawU(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox()); + } + + public List createMany(File suggestedFile) throws IOException { + if (fileFormat == FileFormat.UTXT) { + ug.getCharArea().print(new PrintStream(suggestedFile, "UTF-8")); + } else { + ug.getCharArea().print(new PrintStream(suggestedFile)); + } + return Collections.singletonList(suggestedFile); + } + + public void createOne(OutputStream os, int index) throws IOException { + throw new UnsupportedOperationException(); + } + + public int getNbPages() { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java new file mode 100644 index 000000000..4e4740e60 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java @@ -0,0 +1,164 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4683 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.AbstractMessage; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.sequencediagram.LifeEvent; +import net.sourceforge.plantuml.sequencediagram.LifeEventType; +import net.sourceforge.plantuml.sequencediagram.MessageNumber; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; + +abstract class Step1Abstract { + + private final StringBounder stringBounder; + + private final DrawableSet drawingSet; + + private final AbstractMessage message; + + private double freeY; + + private ComponentType type; + + private Component note; + + Step1Abstract(StringBounder stringBounder, AbstractMessage message, DrawableSet drawingSet, double freeY) { + this.stringBounder = stringBounder; + this.message = message; + this.freeY = freeY; + this.drawingSet = drawingSet; + } + + abstract double prepareMessage(ConstraintSet constraintSet, Collection groupingStructures); + + protected final List getLabelOfMessage(AbstractMessage message) { + if (message.getMessageNumber() == null) { + return message.getLabel(); + } + final List result = new ArrayList(); + result.add(new MessageNumber(message.getMessageNumber())); + result.addAll(message.getLabel()); + return result; + } + + protected final void beforeMessage(LifeEvent n, final double pos) { + final Participant p = n.getParticipant(); + final LifeLine line = drawingSet.getLivingParticipantBox(p).getLifeLine(); + + if (n.getType() != LifeEventType.ACTIVATE) { + return; + } + assert n.getType() == LifeEventType.ACTIVATE; + line.addSegmentVariation(LifeSegmentVariation.LARGER, pos, n.getSpecificBackColor()); + } + + protected final void afterMessage(StringBounder stringBounder, LifeEvent n, final double pos) { + final Participant p = n.getParticipant(); + final LifeLine line = drawingSet.getLivingParticipantBox(p).getLifeLine(); + + if (n.getType() == LifeEventType.ACTIVATE || n.getType() == LifeEventType.CREATE) { + return; + } + + if (n.getType() == LifeEventType.DESTROY) { + final Component comp = drawingSet.getSkin().createComponent(ComponentType.DESTROY, + drawingSet.getSkinParam(), null); + final double delta = comp.getPreferredHeight(stringBounder) / 2; + final LifeDestroy destroy = new LifeDestroy(pos - delta, drawingSet.getLivingParticipantBox(p) + .getParticipantBox(), comp); + drawingSet.addEvent(n, destroy); + } else if (n.getType() != LifeEventType.DEACTIVATE) { + throw new IllegalStateException(); + } + + line.addSegmentVariation(LifeSegmentVariation.SMALLER, pos, n.getSpecificBackColor()); + } + + protected final ComponentType getType() { + return type; + } + + protected final void setType(ComponentType type) { + this.type = type; + } + + protected final Component getNote() { + return note; + } + + protected final void setNote(Component note) { + this.note = note; + } + + protected final StringBounder getStringBounder() { + return stringBounder; + } + + protected final AbstractMessage getMessage() { + return message; + } + + protected final DrawableSet getDrawingSet() { + return drawingSet; + } + + protected final double getFreeY() { + return freeY; + } + + protected final void incFreeY(double v) { + freeY += v; + } + + protected final NoteBox createNoteBox(StringBounder stringBounder, Arrow arrow, Component noteComp, NotePosition notePosition) { + final LivingParticipantBox p = arrow.getParticipantAt(stringBounder, notePosition); + final NoteBox noteBox = new NoteBox(arrow.getStartingY(), noteComp, p, null, notePosition); + + if (arrow instanceof MessageSelfArrow && notePosition == NotePosition.RIGHT) { + noteBox.pushToRight(arrow.getPreferredWidth(stringBounder)); + } + + return noteBox; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java new file mode 100644 index 000000000..9ed9c92d9 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java @@ -0,0 +1,214 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5275 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.Collection; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.sequencediagram.LifeEvent; +import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.skin.ComponentType; + +class Step1Message extends Step1Abstract { + + private final MessageArrow messageArrow; + + Step1Message(StringBounder stringBounder, Message message, DrawableSet drawingSet, double freeY) { + super(stringBounder, message, drawingSet, freeY); + + final double x1 = getParticipantBox1().getCenterX(stringBounder); + final double x2 = getParticipantBox2().getCenterX(stringBounder); + + this.setType(isSelfMessage() ? getSelfArrowType(message) : getArrowType(message, x1, x2)); + + if (isSelfMessage()) { + this.messageArrow = null; + } else { + this.messageArrow = new MessageArrow(freeY, drawingSet.getSkin(), drawingSet.getSkin().createComponent( + getType(), drawingSet.getSkinParam(), getLabelOfMessage(message)), getLivingParticipantBox1(), + getLivingParticipantBox2()); + } + + if (message.getNote() != null) { + final ISkinParam skinParam = new SkinParamBackcolored(drawingSet.getSkinParam(), message + .getSpecificBackColor()); + setNote(drawingSet.getSkin().createComponent(ComponentType.NOTE, drawingSet.getSkinParam(), + message.getNote())); + } + + } + + double prepareMessage(ConstraintSet constraintSet, Collection groupingStructures) { + final Arrow graphic = createArrow(); + final double arrowYStartLevel = graphic.getArrowYStartLevel(getStringBounder()); + final double arrowYEndLevel = graphic.getArrowYEndLevel(getStringBounder()); + + //final double delta1 = isSelfMessage() ? 4 : 0; + final double delta1 = 0; + + for (LifeEvent lifeEvent : getMessage().getLiveEvents()) { + beforeMessage(lifeEvent, arrowYStartLevel + delta1); + } + + final double length; + if (isSelfMessage()) { + length = graphic.getArrowOnlyWidth(getStringBounder()) + + getLivingParticipantBox1().getLiveThicknessAt(getStringBounder(), arrowYStartLevel).getLength(); + } else { + length = graphic.getArrowOnlyWidth(getStringBounder()) + + getLivingParticipantBox(NotePosition.LEFT).getLifeLine().getRightShift(arrowYStartLevel) + + getLivingParticipantBox(NotePosition.RIGHT).getLifeLine().getLeftShift(arrowYStartLevel); + } + + incFreeY(graphic.getPreferredHeight(getStringBounder())); + double marginActivateAndDeactive = 0; + if (getMessage().isActivateAndDeactive()) { + marginActivateAndDeactive = 30; + incFreeY(marginActivateAndDeactive); + } + getDrawingSet().addEvent(getMessage(), graphic); + + if (isSelfMessage()) { + constraintSet.getConstraintAfter(getParticipantBox1()).ensureValue(length); + } else { + constraintSet.getConstraint(getParticipantBox1(), getParticipantBox2()).ensureValue(length); + } + + for (LifeEvent lifeEvent : getMessage().getLiveEvents()) { + afterMessage(getStringBounder(), lifeEvent, arrowYEndLevel + marginActivateAndDeactive - delta1); + } + + if (groupingStructures != null && graphic instanceof InGroupable) { + for (InGroupableList groupingStructure : groupingStructures) { + groupingStructure.addInGroupable((InGroupable) graphic); + groupingStructure.addInGroupable(getLivingParticipantBox1()); + if (isSelfMessage() == false) { + groupingStructure.addInGroupable(getLivingParticipantBox2()); + } + } + } + + return getFreeY(); + } + + private boolean isSelfMessage() { + return getParticipantBox1().equals(getParticipantBox2()); + } + + private ParticipantBox getParticipantBox1() { + return getLivingParticipantBox1().getParticipantBox(); + } + + private ParticipantBox getParticipantBox2() { + return getLivingParticipantBox2().getParticipantBox(); + } + + private LivingParticipantBox getLivingParticipantBox1() { + return getDrawingSet().getLivingParticipantBox(((Message) getMessage()).getParticipant1()); + } + + private LivingParticipantBox getLivingParticipantBox2() { + return getDrawingSet().getLivingParticipantBox(((Message) getMessage()).getParticipant2()); + } + + private LivingParticipantBox getLivingParticipantBox(NotePosition position) { + if (isSelfMessage()) { + throw new IllegalStateException(); + } + return messageArrow.getParticipantAt(getStringBounder(), position); + } + + private Arrow createArrow() { + if (getMessage().isCreate()) { + return createArrowCreate(); + } + final MessageSelfArrow messageSelfArrow = new MessageSelfArrow(getFreeY(), getDrawingSet().getSkin(), + getDrawingSet().getSkin().createComponent(getType(), getDrawingSet().getSkinParam(), + getLabelOfMessage(getMessage())), getLivingParticipantBox1()); + if (getMessage().getNote() != null && isSelfMessage()) { + final NoteBox noteBox = createNoteBox(getStringBounder(), messageSelfArrow, getNote(), getMessage() + .getNotePosition()); + return new ArrowAndNoteBox(getStringBounder(), messageSelfArrow, noteBox); + } else if (getMessage().getNote() != null) { + final NoteBox noteBox = createNoteBox(getStringBounder(), messageArrow, getNote(), getMessage() + .getNotePosition()); + return new ArrowAndNoteBox(getStringBounder(), messageArrow, noteBox); + } else if (isSelfMessage()) { + return messageSelfArrow; + } else { + return messageArrow; + } + } + + private Arrow createArrowCreate() { + getLivingParticipantBox2().create(getFreeY()); + if (getMessage().getNote() != null) { + final ArrowAndParticipant arrowAndParticipant = new ArrowAndParticipant(getStringBounder(), messageArrow, + getParticipantBox2()); + final NoteBox noteBox = createNoteBox(getStringBounder(), arrowAndParticipant, getNote(), getMessage() + .getNotePosition()); + if (getMessage().getNotePosition() == NotePosition.RIGHT) { + noteBox.pushToRight(getParticipantBox2().getPreferredWidth(getStringBounder()) / 2); + } + return new ArrowAndNoteBox(getStringBounder(), arrowAndParticipant, noteBox); + } + return new ArrowAndParticipant(getStringBounder(), messageArrow, getParticipantBox2()); + } + + private ComponentType getSelfArrowType(Message m) { + return m.isDotted() ? ComponentType.DOTTED_SELF_ARROW : ComponentType.SELF_ARROW; + } + + private ComponentType getArrowType(Message m, final double x1, final double x2) { + ComponentType result = null; + if (x2 > x1) { + result = ComponentType.ARROW; + } else { + result = ComponentType.RETURN_ARROW; + } + if (m.isDotted()) { + result = result.getDotted(); + } + if (m.isFull() == false) { + result = result.getAsync(); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java new file mode 100644 index 000000000..4b8d7fb03 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java @@ -0,0 +1,155 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupable; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; +import net.sourceforge.plantuml.sequencediagram.LifeEvent; +import net.sourceforge.plantuml.sequencediagram.MessageExo; +import net.sourceforge.plantuml.sequencediagram.MessageExoType; +import net.sourceforge.plantuml.sequencediagram.MessageNumber; +import net.sourceforge.plantuml.skin.ComponentType; + +class Step1MessageExo extends Step1Abstract { + + private final MessageExoArrow messageArrow; + + Step1MessageExo(StringBounder stringBounder, MessageExo message, DrawableSet drawingSet, double freeY) { + super(stringBounder, message, drawingSet, freeY); + + setType(getArrowType(message)); + + this.messageArrow = new MessageExoArrow(freeY, drawingSet.getSkin(), drawingSet.getSkin().createComponent( + getType(), drawingSet.getSkinParam(), getLabelOfMessage(message)), getLivingParticipantBox(), message + .getType()); + + if (message.getNote() != null) { + final ISkinParam skinParam = new SkinParamBackcolored(drawingSet.getSkinParam(), message + .getSpecificBackColor()); + setNote(drawingSet.getSkin().createComponent(ComponentType.NOTE, drawingSet.getSkinParam(), + message.getNote())); + // throw new UnsupportedOperationException(); + } + + } + + double prepareMessage(ConstraintSet constraintSet, Collection groupingStructures) { + final Arrow graphic = createArrow(); + final double arrowYStartLevel = graphic.getArrowYStartLevel(getStringBounder()); + final double arrowYEndLevel = graphic.getArrowYEndLevel(getStringBounder()); + + for (LifeEvent lifeEvent : getMessage().getLiveEvents()) { + beforeMessage(lifeEvent, arrowYStartLevel); + } + + final double length = graphic.getArrowOnlyWidth(getStringBounder()); + incFreeY(graphic.getPreferredHeight(getStringBounder())); + double marginActivateAndDeactive = 0; + if (getMessage().isActivateAndDeactive()) { + marginActivateAndDeactive = 30; + incFreeY(marginActivateAndDeactive); + } + getDrawingSet().addEvent(getMessage(), graphic); + + final LivingParticipantBox livingParticipantBox = getLivingParticipantBox(); + if (messageArrow.getType().isRightBorder()) { + constraintSet.getConstraint(livingParticipantBox.getParticipantBox(), constraintSet.getLastborder()) + .ensureValue(length); + } else { + constraintSet.getConstraint(constraintSet.getFirstBorder(), livingParticipantBox.getParticipantBox()) + .ensureValue(length); + } + + for (LifeEvent lifeEvent : getMessage().getLiveEvents()) { + afterMessage(getStringBounder(), lifeEvent, arrowYEndLevel + marginActivateAndDeactive); + } + + if (groupingStructures != null && graphic instanceof InGroupable) { + for (InGroupableList groupingStructure : groupingStructures) { + groupingStructure.addInGroupable((InGroupable) graphic); + groupingStructure.addInGroupable(livingParticipantBox); + groupingStructure.addInGroupable(livingParticipantBox); + } + } + + return getFreeY(); + } + + private LivingParticipantBox getLivingParticipantBox() { + return getDrawingSet().getLivingParticipantBox(((MessageExo) getMessage()).getParticipant()); + } + + private List getLabelOfMessage(MessageExo message) { + if (message.getMessageNumber() == null) { + return message.getLabel(); + } + final List result = new ArrayList(); + result.add(new MessageNumber(message.getMessageNumber())); + result.addAll(message.getLabel()); + return result; + } + + private Arrow createArrow() { + if (getMessage().getNote() == null) { + return messageArrow; + } + final NoteBox toto = createNoteBox(getStringBounder(), messageArrow, getNote(), getMessage().getNotePosition()); + return new ArrowAndNoteBox(getStringBounder(), messageArrow, toto); + } + + private ComponentType getArrowType(MessageExo m) { + ComponentType result = null; + final MessageExoType type = m.getType(); + if (type.getDirection() == 1) { + result = ComponentType.ARROW; + } else { + result = ComponentType.RETURN_ARROW; + } + if (m.isDotted()) { + result = result.getDotted(); + } + if (m.isFull() == false) { + result = result.getAsync(); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBar.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBar.java new file mode 100644 index 000000000..8163ee9a3 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBar.java @@ -0,0 +1,110 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public class VirtualHBar implements Pushable { + + private static int CPT = 0; + + private final double width; + private final VirtualHBarType type; + private double x; + private final double startingY; + private double endingY; + + private int cpt = CPT++; + + public VirtualHBar(double width, VirtualHBarType type, double startingY) { + this.width = width; + this.type = type; + this.x = width / 2; + this.startingY = startingY; + } + + @Override + public String toString() { + return "VHB" + cpt + " " + x + " " + startingY + "-" + endingY; + } + + public VirtualHBarType getType() { + return type; + } + + public double getWidth() { + return width; + } + + public double getCenterX(StringBounder stringBounder) { + return x; + } + + public void pushToLeft(double deltaX) { + x += deltaX; + } + + public final double getEndingY() { + return endingY; + } + + public final void setEndingY(double endingY) { + if (endingY <= startingY) { + throw new IllegalArgumentException(); + } + this.endingY = endingY; + } + + public final double getStartingY() { + return startingY; + } + + public boolean canBeOnTheSameLine(VirtualHBar bar) { + if (this.x != bar.x) { + return false; + } + if (this.startingY >= bar.endingY) { + return true; + } + if (this.endingY <= bar.startingY) { + return true; + } + return false; + } + + public double getPreferredWidth(StringBounder stringBounder) { + throw new UnsupportedOperationException(); + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBarType.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBarType.java new file mode 100644 index 000000000..17970c233 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBarType.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.graphic; + +public enum VirtualHBarType { + START, END + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/skin/AbstractComponent.java b/src/net/sourceforge/plantuml/skin/AbstractComponent.java new file mode 100644 index 000000000..542d98506 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/AbstractComponent.java @@ -0,0 +1,92 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4168 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public abstract class AbstractComponent implements Component { + + final protected void stroke(Graphics2D g2d, float dash, float thickness) { + final float[] style = { dash, dash }; + g2d.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, style, 0)); + } + + final protected void stroke(UGraphic ug, int dash, double thickness) { + ug.getParam().setStroke(new UStroke(dash, thickness)); + } + + final protected void stroke(Graphics2D g2d, float dash) { + stroke(g2d, dash, 1); + } + + final protected void stroke(UGraphic ug, int dash) { + stroke(ug, dash, 1); + } + + abstract protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse); + + protected void drawBackgroundInternalU(UGraphic ug, Dimension2D dimensionToUse) { + } + + public final void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context) { + final double dx = ug.getTranslateX(); + final double dy = ug.getTranslateY(); + ug.translate(getPaddingX(), getPaddingY()); + if (context.isBackground()) { + drawBackgroundInternalU(ug, dimensionToUse); + } else { + drawInternalU(ug, dimensionToUse); + } + ug.setTranslate(dx, dy); + } + + public double getPaddingX() { + return 0; + } + + public double getPaddingY() { + return 0; + } + + public abstract double getPreferredWidth(StringBounder stringBounder); + + public abstract double getPreferredHeight(StringBounder stringBounder); + +} diff --git a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java new file mode 100644 index 000000000..9056d0cb0 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java @@ -0,0 +1,132 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5277 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; + +public abstract class AbstractTextualComponent extends AbstractComponent { + + private final List strings; + + private final int marginX1; + private final int marginX2; + private final int marginY; + + private final TextBlock textBlock; + + private final Font font; + private final Color fontColor; + + public AbstractTextualComponent(CharSequence label, Color fontColor, Font font, + HorizontalAlignement horizontalAlignement, int marginX1, int marginX2, int marginY) { + this(Arrays.asList(label == null ? "" : label), fontColor, font, horizontalAlignement, marginX1, marginX2, + marginY); + } + + public AbstractTextualComponent(List strings, Color fontColor, Font font, + HorizontalAlignement horizontalAlignement, int marginX1, int marginX2, int marginY) { + this.font = font; + this.fontColor = fontColor; + this.marginX1 = marginX1; + this.marginX2 = marginX2; + this.marginY = marginY; + this.strings = strings; + + textBlock = TextBlockUtils.create(strings, font, fontColor, horizontalAlignement); + } + + final protected TextBlock getTextBlock() { + return textBlock; + } + + final protected double getPureTextWidth(StringBounder stringBounder) { + final TextBlock textBlock = getTextBlock(); + final Dimension2D size = getSize(stringBounder, textBlock); + return size.getWidth(); + } + + final public double getTextWidth(StringBounder stringBounder) { + return getPureTextWidth(stringBounder) + marginX1 + marginX2; + } + + // For cache + private Dimension2D size; + + private Dimension2D getSize(StringBounder stringBounder, final TextBlock textBlock) { + if (size == null) { + size = textBlock.calculateDimension(stringBounder); + } + return size; + } + + final protected double getTextHeight(StringBounder stringBounder) { + final TextBlock textBlock = getTextBlock(); + final Dimension2D size = getSize(stringBounder, textBlock); + return size.getHeight() + 2 * marginY; + } + + final protected List getLabels() { + return strings; + } + + final protected int getMarginX1() { + return marginX1; + } + + final protected int getMarginX2() { + return marginX2; + } + + final protected int getMarginY() { + return marginY; + } + + final protected Font getFont() { + return font; + } + + protected Color getFontColor() { + return fontColor; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/ArrowComponent.java b/src/net/sourceforge/plantuml/skin/ArrowComponent.java new file mode 100644 index 000000000..0737cc05e --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/ArrowComponent.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public interface ArrowComponent extends Component { + + Point2D getStartPoint(StringBounder stringBounder, Dimension2D dimensionToUse); + + Point2D getEndPoint(StringBounder stringBounder, Dimension2D dimensionToUse); + +} diff --git a/src/net/sourceforge/plantuml/skin/CircleInterface.java b/src/net/sourceforge/plantuml/skin/CircleInterface.java new file mode 100644 index 000000000..1aaf23eb0 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/CircleInterface.java @@ -0,0 +1,99 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5343 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.Color; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class CircleInterface implements UDrawable { + + private final float thickness; + private final double headDiam; + private final Color backgroundColor; + private final Color foregroundColor; + + public CircleInterface(Color backgroundColor, Color foregroundColor) { + this(backgroundColor, foregroundColor, 16, 2); + } + + public CircleInterface(Color backgroundColor, Color foregroundColor, double headDiam, float thickness) { + this.backgroundColor = backgroundColor; + this.foregroundColor = foregroundColor; + this.headDiam = headDiam; + this.thickness = thickness; + } + +// public void draw(Graphics2D g2d) { +// +// g2d.setStroke(new BasicStroke(thickness)); +// +// final Shape head = new Ellipse2D.Double(thickness, thickness, headDiam, headDiam); +// +// g2d.setColor(backgroundColor); +// g2d.fill(head); +// +// g2d.setColor(foregroundColor); +// g2d.draw(head); +// +// g2d.setStroke(new BasicStroke()); +// throw new UnsupportedOperationException(); +// } + + public void drawU(UGraphic ug) { + + ug.getParam().setStroke(new UStroke(thickness)); + + final UEllipse head = new UEllipse(headDiam, headDiam); + + ug.getParam().setBackcolor(backgroundColor); + ug.getParam().setColor(foregroundColor); + ug.draw(thickness, thickness, head); + + ug.getParam().setStroke(new UStroke()); + } + + + public double getPreferredWidth(StringBounder stringBounder) { + return headDiam + 2 * thickness; + } + + public double getPreferredHeight(StringBounder stringBounder) { + return headDiam + 2 * thickness; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/Component.java b/src/net/sourceforge/plantuml/skin/Component.java new file mode 100644 index 000000000..97ce302df --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/Component.java @@ -0,0 +1,49 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4168 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public interface Component { + + double getPreferredWidth(StringBounder stringBounder); + + double getPreferredHeight(StringBounder stringBounder); + + void drawU(UGraphic ug, Dimension2D dimensionToUse, Context2D context); + +} diff --git a/src/net/sourceforge/plantuml/skin/ComponentType.java b/src/net/sourceforge/plantuml/skin/ComponentType.java new file mode 100644 index 000000000..f723782ec --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/ComponentType.java @@ -0,0 +1,130 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5191 $ + * + */ +package net.sourceforge.plantuml.skin; + +public enum ComponentType { + ACTOR_HEAD, ACTOR_LINE, ACTOR_TAIL, + + ALIVE_LINE, DESTROY, + + ARROW, DOTTED_ARROW, DOTTED_SELF_ARROW, RETURN_ARROW, RETURN_DOTTED_ARROW, SELF_ARROW, + + ASYNC_ARROW, ASYNC_DOTTED_ARROW, ASYNC_RETURN_ARROW, ASYNC_RETURN_DOTTED_ARROW, + + GROUPING_BODY, GROUPING_ELSE, GROUPING_HEADER, GROUPING_TAIL, + + NEWPAGE, NOTE, DIVIDER, + + ENGLOBER, + + PARTICIPANT_HEAD, PARTICIPANT_LINE, PARTICIPANT_TAIL, + + TITLE, SIGNATURE; + + public ComponentType getDotted() { + if (this == ComponentType.ARROW) { + return ComponentType.DOTTED_ARROW; + } else if (this == ComponentType.DOTTED_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.DOTTED_SELF_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.RETURN_ARROW) { + return ComponentType.RETURN_DOTTED_ARROW; + } else if (this == ComponentType.RETURN_DOTTED_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.SELF_ARROW) { + return ComponentType.DOTTED_SELF_ARROW; + } else if (this == ComponentType.ASYNC_ARROW) { + return ComponentType.ASYNC_DOTTED_ARROW; + } else if (this == ComponentType.ASYNC_DOTTED_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_RETURN_ARROW) { + return ComponentType.ASYNC_RETURN_DOTTED_ARROW; + } else if (this == ComponentType.ASYNC_RETURN_DOTTED_ARROW) { + throw new IllegalStateException(); + } + throw new UnsupportedOperationException(); + } + + public ComponentType getAsync() { + if (this == ComponentType.ARROW) { + return ComponentType.ASYNC_ARROW; + } else if (this == ComponentType.DOTTED_ARROW) { + return ComponentType.ASYNC_DOTTED_ARROW; + } else if (this == ComponentType.DOTTED_SELF_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.RETURN_ARROW) { + return ComponentType.ASYNC_RETURN_ARROW; + } else if (this == ComponentType.RETURN_DOTTED_ARROW) { + return ComponentType.ASYNC_RETURN_DOTTED_ARROW; + } else if (this == ComponentType.SELF_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_DOTTED_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_RETURN_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_RETURN_DOTTED_ARROW) { + throw new IllegalStateException(); + } + throw new UnsupportedOperationException(); + } + + public ComponentType getReverse() { + if (this == ComponentType.ARROW) { + return ComponentType.RETURN_ARROW; + } else if (this == ComponentType.DOTTED_ARROW) { + return ComponentType.RETURN_DOTTED_ARROW; + } else if (this == ComponentType.DOTTED_SELF_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.RETURN_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.RETURN_DOTTED_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.SELF_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_ARROW) { + return ComponentType.ASYNC_RETURN_ARROW; + } else if (this == ComponentType.ASYNC_DOTTED_ARROW) { + return ComponentType.ASYNC_RETURN_DOTTED_ARROW; + } else if (this == ComponentType.ASYNC_RETURN_ARROW) { + throw new IllegalStateException(); + } else if (this == ComponentType.ASYNC_RETURN_DOTTED_ARROW) { + throw new IllegalStateException(); + } + throw new UnsupportedOperationException(); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/Context2D.java b/src/net/sourceforge/plantuml/skin/Context2D.java new file mode 100644 index 000000000..e38e12188 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/Context2D.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.skin; + +public interface Context2D { + boolean isBackground(); +} diff --git a/src/net/sourceforge/plantuml/skin/GrayComponent.java b/src/net/sourceforge/plantuml/skin/GrayComponent.java new file mode 100644 index 000000000..3fa42da79 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/GrayComponent.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +class GrayComponent extends AbstractComponent { + + private static final Font NORMAL = new Font("SansSerif", Font.PLAIN, 7); + + private final ComponentType type; + + public GrayComponent(ComponentType type) { + this.type = type; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + ug.getParam().setBackcolor(Color.LIGHT_GRAY); + ug.getParam().setColor(Color.BLACK); + ug.draw(0, 0, new URectangle(getPreferredWidth(stringBounder), getPreferredHeight(stringBounder))); + + final String n = type.name(); + final int split = 9; + final List strings = new ArrayList(); + for (int i = 0; i < n.length(); i += split) { + strings.add(n.substring(i, Math.min(i + split, n.length()))); + } + + final TextBlock textBlock = TextBlockUtils.create(strings, NORMAL, Color.BLACK, HorizontalAlignement.LEFT); + textBlock.drawU(ug, 0, 0); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 42; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 42; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/ProtectedSkin.java b/src/net/sourceforge/plantuml/skin/ProtectedSkin.java new file mode 100644 index 000000000..43156134e --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/ProtectedSkin.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4246 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.util.List; + +import net.sourceforge.plantuml.ISkinParam; + +public class ProtectedSkin implements Skin { + + final private Skin skinToProtect; + + public ProtectedSkin(Skin skinToProtect) { + this.skinToProtect = skinToProtect; + + } + + public Component createComponent(ComponentType type, ISkinParam param, List stringsToDisplay) { + Component result = null; + try { + result = skinToProtect.createComponent(type, param, stringsToDisplay); + } catch (Throwable e) { + e.printStackTrace(); + } + if (result == null) { + return new GrayComponent(type); + } + return result; + } + + public Object getProtocolVersion() { + return skinToProtect.getProtocolVersion(); + } +} diff --git a/src/net/sourceforge/plantuml/skin/SimpleContext2D.java b/src/net/sourceforge/plantuml/skin/SimpleContext2D.java new file mode 100644 index 000000000..a7841497c --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/SimpleContext2D.java @@ -0,0 +1,48 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.skin; + +public class SimpleContext2D implements Context2D { + + private final boolean isBackground; + + public SimpleContext2D(boolean isBackground) { + this.isBackground = isBackground; + } + + public boolean isBackground() { + return isBackground; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/Skin.java b/src/net/sourceforge/plantuml/skin/Skin.java new file mode 100644 index 000000000..a030af5eb --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/Skin.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4246 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.util.List; + +import net.sourceforge.plantuml.ISkinParam; + +public interface Skin { + + Object getProtocolVersion(); + + Component createComponent(ComponentType type, ISkinParam param, List stringsToDisplay); + +} diff --git a/src/net/sourceforge/plantuml/skin/SkinUtils.java b/src/net/sourceforge/plantuml/skin/SkinUtils.java new file mode 100644 index 000000000..e8ec997a7 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/SkinUtils.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.util.ArrayList; +import java.util.List; + +public class SkinUtils { + + static public Skin loadSkin(String className) { + final List errors = new ArrayList(); + Skin result = tryLoading(className, errors); + if (result != null) { + return result; + } + result = tryLoading("net.sourceforge.plantuml.skin." + className, errors); + if (result != null) { + return result; + } + final String packageName = className.toLowerCase(); + result = tryLoading(packageName + "." + className, errors); + if (result != null) { + return result; + } + result = tryLoading("net.sourceforge.plantuml.skin." + packageName + "." + className, errors); + if (result != null) { + return result; + } + for (String e : errors) { + System.err.println(e); + } + return null; + } + + private static Skin tryLoading(String className, List errors) { + try { + final Class cl = (Class) Class.forName(className); + return cl.newInstance(); + } catch (Exception e) { + errors.add("Cannot load " + className); + return null; + } + } +} diff --git a/src/net/sourceforge/plantuml/skin/StickMan.java b/src/net/sourceforge/plantuml/skin/StickMan.java new file mode 100644 index 000000000..3c85e4242 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/StickMan.java @@ -0,0 +1,142 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4189 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class StickMan implements UDrawable { + + private final float thickness = 2; + + private final double armsY = 8; + private final double armsLenght = 13; + private final double bodyLenght = 27; + private final double legsX = 13; + private final double legsY = 15; + private final double headDiam = 16; + + private final Color backgroundColor; + private final Color foregroundColor; + + public StickMan(Color backgroundColor, Color foregroundColor) { + this.backgroundColor = backgroundColor; + this.foregroundColor = foregroundColor; + } + + public void draw(Graphics2D g2d) { + + g2d.setStroke(new BasicStroke(thickness)); + + final double startX = Math.max(armsLenght, legsX) - headDiam / 2.0 + thickness; + + final Shape head = new Ellipse2D.Double(startX, thickness, headDiam, headDiam); + final Rectangle2D headBound = head.getBounds2D(); + + final double centerX = headBound.getCenterX(); + + final Shape body = new Line2D.Double(centerX, headBound.getMaxY(), centerX, headBound.getMaxY() + bodyLenght); + + final Shape arms = new Line2D.Double(centerX - armsLenght, headBound.getMaxY() + armsY, centerX + armsLenght, + headBound.getMaxY() + armsY); + + final double y = body.getBounds2D().getMaxY(); + + final Shape legs1 = new Line2D.Double(centerX, y, centerX - legsX, y + legsY); + final Shape legs2 = new Line2D.Double(centerX, y, centerX + legsX, y + legsY); + + g2d.setColor(backgroundColor); + g2d.fill(head); + + g2d.setColor(foregroundColor); + g2d.draw(head); + g2d.draw(body); + g2d.draw(arms); + g2d.draw(legs1); + g2d.draw(legs2); + + g2d.setStroke(new BasicStroke()); + throw new UnsupportedOperationException(); + } + + public void drawU(UGraphic ug) { + + ug.getParam().setStroke(new UStroke(thickness)); + + final double startX = Math.max(armsLenght, legsX) - headDiam / 2.0 + thickness; + + final UEllipse head = new UEllipse(headDiam, headDiam); + final double centerX = startX + headDiam / 2; + + final ULine body = new ULine(0, bodyLenght); + + final ULine arms = new ULine(armsLenght * 2, 0); + + final double y = headDiam + thickness + bodyLenght; + + final ULine legs1 = new ULine(-legsX, legsY); + final ULine legs2 = new ULine(legsX, legsY); + + ug.getParam().setBackcolor(backgroundColor); + ug.getParam().setColor(foregroundColor); + ug.draw(startX, thickness, head); + + ug.draw(centerX, headDiam + thickness, body); + ug.draw(centerX - armsLenght, headDiam + thickness + armsY, arms); + ug.draw(centerX, y, legs1); + ug.draw(centerX, y, legs2); + + ug.getParam().setStroke(new UStroke()); + } + + public double getPreferredWidth(StringBounder stringBounder) { + return Math.max(armsLenght, legsX) * 2 + 2 * thickness; + } + + public double getPreferredHeight(StringBounder stringBounder) { + return headDiam + bodyLenght + legsY + 2 * thickness; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/UDrawable.java b/src/net/sourceforge/plantuml/skin/UDrawable.java new file mode 100644 index 000000000..30862730c --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/UDrawable.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3836 $ + * + */ +package net.sourceforge.plantuml.skin; + +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public interface UDrawable { + + public void drawU(UGraphic ug); + +} diff --git a/src/net/sourceforge/plantuml/skin/VisibilityModifier.java b/src/net/sourceforge/plantuml/skin/VisibilityModifier.java new file mode 100644 index 000000000..88d0dd78b --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/VisibilityModifier.java @@ -0,0 +1,208 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4189 $ + * + */ +package net.sourceforge.plantuml.skin; + +import java.awt.Color; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public enum VisibilityModifier { + PRIVATE_FIELD(ColorParam.iconPrivate, null), PROTECTED_FIELD(ColorParam.iconProtected, null), PACKAGE_PRIVATE_FIELD( + ColorParam.iconPackage, null), PUBLIC_FIELD(ColorParam.iconPublic, null), + + PRIVATE_METHOD(ColorParam.iconPrivate, ColorParam.iconPrivateBackground), PROTECTED_METHOD( + ColorParam.iconProtected, ColorParam.iconProtectedBackground), PACKAGE_PRIVATE_METHOD( + ColorParam.iconPackage, ColorParam.iconPackageBackground), PUBLIC_METHOD(ColorParam.iconPublic, + ColorParam.iconPublicBackground); + + private final ColorParam foreground; + private final ColorParam background; + + private VisibilityModifier(ColorParam foreground, ColorParam background) { + this.foreground = foreground; + this.background = background; + } + + public UDrawable getUDrawable(final int size, final Color foregroundColor, final Color backgoundColor) { + return new UDrawable() { + public void drawU(UGraphic ug) { + drawInternal(ug, size, foregroundColor, backgoundColor); + } + }; + } + + private void drawInternal(UGraphic ug, int size, final Color foregroundColor, final Color backgoundColor) { + ug.getParam().setBackcolor(backgoundColor); + ug.getParam().setColor(foregroundColor); + size = ensureEven(size); + switch (this) { + case PACKAGE_PRIVATE_FIELD: + drawTriangle(ug, false, size); + break; + + case PRIVATE_FIELD: + drawSquare(ug, false, size); + break; + + case PROTECTED_FIELD: + drawDiamond(ug, false, size); + break; + + case PUBLIC_FIELD: + drawCircle(ug, false, size); + break; + + case PACKAGE_PRIVATE_METHOD: + drawTriangle(ug, true, size); + break; + + case PRIVATE_METHOD: + drawSquare(ug, true, size); + break; + + case PROTECTED_METHOD: + drawDiamond(ug, true, size); + break; + + case PUBLIC_METHOD: + drawCircle(ug, true, size); + break; + + default: + throw new IllegalStateException(); + } + } + + private void drawSquare(UGraphic ug, boolean filled, int size) { + ug.draw(2, 2, new URectangle(size - 4, size - 4)); + } + + private void drawCircle(UGraphic ug, boolean filled, int size) { + ug.draw(2, 2, new UEllipse(size - 4, size - 4)); + } + + static private int ensureEven(int n) { + if (n % 2 == 1) { + n--; + } + return n; + } + + private void drawDiamond(UGraphic ug, boolean filled, int size) { + final UPolygon poly = new UPolygon(); + size -= 2; + poly.addPoint(size / 2.0, 0); + poly.addPoint(size, size / 2.0); + poly.addPoint(size / 2.0, size); + poly.addPoint(0, size / 2.0); + ug.draw(1, 0, poly); + } + + private void drawTriangle(UGraphic ug, boolean filled, int size) { + final UPolygon poly = new UPolygon(); + size -= 2; + poly.addPoint(size / 2.0, 1); + poly.addPoint(0, size - 1); + poly.addPoint(size, size - 1); + ug.draw(1, 0, poly); + } + + public static boolean isVisibilityCharacter(char c) { + if (c == '-') { + return true; + } + if (c == '#') { + return true; + } + if (c == '+') { + return true; + } + if (c == '~') { + return true; + } + return false; + } + + public static VisibilityModifier getVisibilityModifier(char c, boolean isField) { + if (isField) { + return getVisibilityModifierForField(c); + } + return getVisibilityModifierForMethod(c); + } + + private static VisibilityModifier getVisibilityModifierForField(char c) { + if (c == '-') { + return VisibilityModifier.PRIVATE_FIELD; + } + if (c == '#') { + return VisibilityModifier.PROTECTED_FIELD; + } + if (c == '+') { + return VisibilityModifier.PUBLIC_FIELD; + } + if (c == '~') { + return VisibilityModifier.PACKAGE_PRIVATE_FIELD; + } + return null; + } + + private static VisibilityModifier getVisibilityModifierForMethod(char c) { + if (c == '-') { + return VisibilityModifier.PRIVATE_METHOD; + } + if (c == '#') { + return VisibilityModifier.PROTECTED_METHOD; + } + if (c == '+') { + return VisibilityModifier.PUBLIC_METHOD; + } + if (c == '~') { + return VisibilityModifier.PACKAGE_PRIVATE_METHOD; + } + return null; + } + + public final ColorParam getForeground() { + return foreground; + } + + public final ColorParam getBackground() { + return background; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/AbstractComponentBlueModernArrow.java b/src/net/sourceforge/plantuml/skin/bluemodern/AbstractComponentBlueModernArrow.java new file mode 100644 index 000000000..671cf9daf --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/AbstractComponentBlueModernArrow.java @@ -0,0 +1,95 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5355 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; + +public abstract class AbstractComponentBlueModernArrow extends AbstractTextualComponent { + + private final int arrowDeltaX = 12; + private final int arrowDeltaY = 10; + + private final int arrowDeltaX2 = 10; + private final int arrowDeltaY2 = 5; + private final boolean dotted; + private final boolean full; + private final Color foregroundColor; + + public AbstractComponentBlueModernArrow(Color foregroundColor, Color fontColor, Font font, + List stringsToDisplay, boolean dotted, boolean full) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.LEFT, 17, 17, 2); + this.dotted = dotted; + this.full = full; + this.foregroundColor = foregroundColor; + } + + protected final Color getForegroundColor() { + return foregroundColor; + } + + final protected int getArrowDeltaX() { + return arrowDeltaX; + } + + final protected int getArrowDeltaY() { + return arrowDeltaY; + } + + final protected int getArrowDeltaY2() { + return arrowDeltaY2; + } + + final protected int getArrowDeltaX2() { + return arrowDeltaX2; + } + + @Override + public final double getPaddingY() { + return 6; + } + + final protected boolean isDotted() { + return dotted; + } + + final protected boolean isFull() { + return full; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java b/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java new file mode 100644 index 000000000..7e6d0b955 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java @@ -0,0 +1,165 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5272 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.skin.rose.ComponentRoseDestroy; +import net.sourceforge.plantuml.skin.rose.ComponentRoseGroupingElse; +import net.sourceforge.plantuml.skin.rose.ComponentRoseTitle; + +public class BlueModern implements Skin { + + private final Font bigFont = new Font("SansSerif", Font.BOLD, 20); + private final Font participantFont = new Font("SansSerif", Font.PLAIN, 17); + private final Font normalFont = new Font("SansSerif", Font.PLAIN, 13); + private final Font smallFont = new Font("SansSerif", Font.BOLD, 11); + + private final Color blue1 = new Color(Integer.parseInt("527BC6", 16)); + private final Color blue2 = new Color(Integer.parseInt("D1DBEF", 16)); + private final Color blue3 = new Color(Integer.parseInt("D7E0F2", 16)); + + private final Color red = new Color(Integer.parseInt("A80036", 16)); + + private final Color lineColor = new Color(Integer.parseInt("989898", 16)); + private final Color borderGroupColor = new Color(Integer.parseInt("BBBBBB", 16)); + + public Component createComponent(ComponentType type, ISkinParam param, List stringsToDisplay) { + + if (type == ComponentType.PARTICIPANT_HEAD) { + return new ComponentBlueModernParticipant(blue1, blue2, Color.WHITE, participantFont, stringsToDisplay); + } + if (type == ComponentType.PARTICIPANT_TAIL) { + return new ComponentBlueModernParticipant(blue1, blue2, Color.WHITE, participantFont, stringsToDisplay); + } + if (type == ComponentType.PARTICIPANT_LINE) { + return new ComponentBlueModernLine(lineColor); + } + if (type == ComponentType.SELF_ARROW) { + return new ComponentBlueModernSelfArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, false, true); + } + if (type == ComponentType.DOTTED_SELF_ARROW) { + return new ComponentBlueModernSelfArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, true, true); + } + if (type == ComponentType.ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, 1, false, true); + } + if (type == ComponentType.ASYNC_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, 1, false, false); + } + if (type == ComponentType.DOTTED_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, 1, true, true); + } + if (type == ComponentType.ASYNC_DOTTED_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, 1, true, false); + } + if (type == ComponentType.RETURN_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, -1, false, true); + } + if (type == ComponentType.ASYNC_RETURN_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, -1, false, + false); + } + if (type == ComponentType.RETURN_DOTTED_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, -1, true, true); + } + if (type == ComponentType.ASYNC_RETURN_DOTTED_ARROW) { + return new ComponentBlueModernArrow(Color.BLACK, Color.BLACK, normalFont, stringsToDisplay, -1, true, false); + } + if (type == ComponentType.ACTOR_HEAD) { + return new ComponentBlueModernActor(blue2, blue1, blue1, participantFont, stringsToDisplay, true); + } + if (type == ComponentType.ACTOR_TAIL) { + return new ComponentBlueModernActor(blue2, blue1, blue1, participantFont, stringsToDisplay, false); + } + if (type == ComponentType.ACTOR_LINE) { + return new ComponentBlueModernLine(lineColor); + } + if (type == ComponentType.NOTE) { + return new ComponentBlueModernNote(Color.WHITE, Color.BLACK, Color.BLACK, normalFont, stringsToDisplay); + } + if (type == ComponentType.ALIVE_LINE) { + return new ComponentBlueModernActiveLine(blue1); + } + if (type == ComponentType.DESTROY) { + return new ComponentRoseDestroy(red); + } + if (type == ComponentType.GROUPING_HEADER) { + return new ComponentBlueModernGroupingHeader(blue1, blue3, borderGroupColor, Color.WHITE, Color.BLACK, + normalFont, smallFont, stringsToDisplay); + } + if (type == ComponentType.GROUPING_BODY) { + return new ComponentBlueModernGroupingBody(blue3, borderGroupColor); + } + if (type == ComponentType.GROUPING_TAIL) { + return new ComponentBlueModernGroupingTail(borderGroupColor); + } + if (type == ComponentType.GROUPING_ELSE) { + return new ComponentRoseGroupingElse(Color.BLACK, smallFont, stringsToDisplay.get(0)); + } + if (type == ComponentType.TITLE) { + return new ComponentRoseTitle(Color.BLACK, bigFont, stringsToDisplay); + } + if (type == ComponentType.NEWPAGE) { + return new ComponentBlueModernNewpage(blue1); + } + if (type == ComponentType.DIVIDER) { + return new ComponentBlueModernDivider(Color.BLACK, normalFont, blue2, blue1, Color.BLACK, stringsToDisplay); + } + if (type == ComponentType.SIGNATURE) { + return new ComponentRoseTitle(Color.BLACK, smallFont, Arrays.asList("This skin was created ", + "in April 2009.")); + } + if (type == ComponentType.ENGLOBER) { + return new ComponentBlueModernEnglober(blue1, blue3, stringsToDisplay, Color.BLACK, param + .getFont(FontParam.SEQUENCE_ENGLOBER)); + } + + return null; + + } + + public Object getProtocolVersion() { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernActiveLine.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernActiveLine.java new file mode 100644 index 000000000..0a48b6907 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernActiveLine.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class ComponentBlueModernActiveLine extends AbstractComponent { + + private final int shadowview = 3; + private final Color foregroundColor; + + public ComponentBlueModernActiveLine(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int x = (int) (dimensionToUse.getWidth() - getPreferredWidth(stringBounder)) / 2; + final ShadowShape shadowShape = new ShadowShape(getPreferredWidth(stringBounder), dimensionToUse.getHeight() + - shadowview, 3); + ug.translate(shadowview, shadowview); + shadowShape.drawU(ug); + ug.translate(-shadowview, -shadowview); + + ug.getParam().setColor(foregroundColor); + ug.getParam().setBackcolor(foregroundColor); + ug.draw(x, 0, new URectangle(getPreferredWidth(stringBounder), (dimensionToUse.getHeight() - shadowview))); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 0; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 10; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernActor.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernActor.java new file mode 100644 index 000000000..3f4f5db0e --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernActor.java @@ -0,0 +1,92 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4738 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.skin.StickMan; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ComponentBlueModernActor extends AbstractTextualComponent { + + private final StickMan stickman; + private final boolean head; + + public ComponentBlueModernActor(Color backgroundColor, Color foregroundColor, Color fontColor, Font font, + List stringsToDisplay, boolean head) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.LEFT, 3, 3, 0); + this.head = head; + stickman = new StickMan(backgroundColor, foregroundColor); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(getFontColor()); + final TextBlock textBlock = getTextBlock(); + final StringBounder stringBounder = ug.getStringBounder(); + final double delta = (getPreferredWidth(stringBounder) - stickman.getPreferredWidth(stringBounder)) / 2; + + if (head) { + textBlock.drawU(ug, getTextMiddlePostion(stringBounder), stickman.getPreferredHeight(stringBounder)); + ug.translate(delta, 0); + } else { + textBlock.drawU(ug, getTextMiddlePostion(stringBounder), 0); + ug.translate(delta, getTextHeight(stringBounder)); + } + stickman.drawU(ug); + + } + + private double getTextMiddlePostion(StringBounder stringBounder) { + return (getPreferredWidth(stringBounder) - getTextWidth(stringBounder)) / 2.0; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return stickman.getPreferredHeight(stringBounder) + getTextHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return Math.max(stickman.getPreferredWidth(stringBounder), getTextWidth(stringBounder)); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernArrow.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernArrow.java new file mode 100644 index 000000000..f04a1d3f3 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernArrow.java @@ -0,0 +1,129 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4634 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernArrow extends AbstractComponentBlueModernArrow { + + private final int direction; + + public ComponentBlueModernArrow(Color foregroundColor, Color fontColor, Font font, + List stringsToDisplay, int direction, boolean dotted, boolean full) { + super(foregroundColor, fontColor, font, stringsToDisplay, dotted, full); + this.direction = direction; + if (direction != 1 && direction != -1) { + throw new IllegalArgumentException(); + } + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int textHeight = (int) getTextHeight(stringBounder); + + ug.getParam().setColor(getForegroundColor()); + ug.getParam().setBackcolor(getForegroundColor()); + + final int x2 = (int) dimensionToUse.getWidth(); + + if (isDotted()) { + stroke(ug, 5, 2); + } else { + ug.getParam().setStroke(new UStroke(2)); + } + + ug.draw(2, textHeight, new ULine(x2 - 4, 0)); + ug.getParam().setStroke(new UStroke()); + + final int direction = getDirection(); + final UPolygon polygon = new UPolygon(); + + if (isFull() == false) { + ug.getParam().setStroke(new UStroke(1.5)); + if (direction == 1) { + ug.draw(x2 - getArrowDeltaX2(), textHeight - getArrowDeltaY2(), new ULine(getArrowDeltaX2(), + getArrowDeltaY2())); + ug.draw(x2 - getArrowDeltaX2(), textHeight + getArrowDeltaY2(), new ULine(getArrowDeltaX2(), + -getArrowDeltaY2())); + } else { + ug.draw(getArrowDeltaX2(), textHeight - getArrowDeltaY2(), new ULine(-getArrowDeltaX2(), + getArrowDeltaY2())); + ug.draw(getArrowDeltaX2(), textHeight + getArrowDeltaY2(), new ULine(-getArrowDeltaX2(), + -getArrowDeltaY2())); + } + ug.getParam().setStroke(new UStroke()); + } else if (direction == 1) { + polygon.addPoint(x2 - getArrowDeltaX(), textHeight - getArrowDeltaY()); + polygon.addPoint(x2, textHeight); + polygon.addPoint(x2 - getArrowDeltaX(), textHeight + getArrowDeltaY()); + } else { + polygon.addPoint(getArrowDeltaX(), textHeight - getArrowDeltaY()); + polygon.addPoint(0, textHeight); + polygon.addPoint(getArrowDeltaX(), textHeight + getArrowDeltaY()); + } + ug.draw(0, 0, polygon); + + getTextBlock().drawU(ug, getMarginX1(), 0); + } + + protected int getDirection(Graphics2D g2d) { + return direction; + } + + protected int getDirection() { + return direction; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + getArrowDeltaY() + 2 * getPaddingY(); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernDivider.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernDivider.java new file mode 100644 index 000000000..d65f56ae2 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernDivider.java @@ -0,0 +1,107 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernDivider extends AbstractTextualComponent { + + private final Color background1; + private final Color background2; + private final Color borderColor; + + public ComponentBlueModernDivider(Color fontColor, Font font, Color background1, Color background2, + Color borderColor, List stringsToDisplay) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.CENTER, 4, 4, 4); + this.background1 = background1; + this.background2 = background2; + this.borderColor = borderColor; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final TextBlock textBlock = getTextBlock(); + final StringBounder stringBounder = ug.getStringBounder(); + final double textWidth = getTextWidth(stringBounder); + final double textHeight = getTextHeight(stringBounder); + + final double deltaX = 6; + final double xpos = (dimensionToUse.getWidth() - textWidth - deltaX) / 2; + final double ypos = (dimensionToUse.getHeight() - textHeight) / 2; + + ug.getParam().setColor(Color.BLACK); + ug.getParam().setBackcolor(Color.BLACK); + + ug.getParam().setStroke(new UStroke(2)); + + ug.draw(0, dimensionToUse.getHeight() / 2 - 1, new ULine(dimensionToUse.getWidth(), 0)); + ug.draw(0, dimensionToUse.getHeight() / 2 + 2, new ULine(dimensionToUse.getWidth(), 0)); + + + final FillRoundShape shape = new FillRoundShape(textWidth + deltaX, textHeight, background1, background2, 5); + ug.translate(xpos, ypos); + shape.drawU(ug); + ug.translate(-xpos, -ypos); + + ug.getParam().setColor(borderColor); + ug.getParam().setBackcolor(null); + ug.draw(xpos, ypos, new URectangle(textWidth + deltaX, textHeight, 5, 5)); + ug.getParam().setStroke(new UStroke()); + + textBlock.drawU(ug, xpos + deltaX, ypos + getMarginY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 20; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder) + 30; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernEnglober.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernEnglober.java new file mode 100644 index 000000000..c983f8ebc --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernEnglober.java @@ -0,0 +1,88 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4258 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernEnglober extends AbstractTextualComponent { + + private final Color borderColor; + private final Color backColor; + + public ComponentBlueModernEnglober(Color borderColor, Color backColor, List strings, + Color fontColor, Font font) { + super(strings, fontColor, font, HorizontalAlignement.CENTER, 4, 4, 1); + this.borderColor = borderColor; + this.backColor = backColor; + } + + @Override + protected void drawBackgroundInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(borderColor); + ug.getParam().setBackcolor(backColor); + ug.getParam().setStroke(new UStroke(2)); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight(), 9, 9)); + final double xpos = (dimensionToUse.getWidth() - getPureTextWidth(ug.getStringBounder())) / 2; + ug.getParam().setStroke(new UStroke()); + getTextBlock().drawU(ug, xpos, 0); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + // ug.getParam().setColor(Color.RED); + // ug.getParam().setBackcolor(Color.YELLOW); + // ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), + // dimensionToUse.getHeight())); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 3; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder) + 10; + } +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingBody.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingBody.java new file mode 100644 index 000000000..02eb0486a --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingBody.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernGroupingBody extends AbstractComponent { + + private final Color foregroundColor; + private final Color generalBackgroundColor; + + public ComponentBlueModernGroupingBody(Color generalBackgroundColor, Color foregroundColor) { + this.foregroundColor = foregroundColor; + this.generalBackgroundColor = generalBackgroundColor; + } + + @Override + protected void drawBackgroundInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(generalBackgroundColor); + ug.getParam().setBackcolor(generalBackgroundColor); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight())); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setStroke(new UStroke(2)); + ug.getParam().setColor(foregroundColor); + + ug.draw(0, 0, new ULine(0, dimensionToUse.getHeight())); + ug.draw(dimensionToUse.getWidth(), 0, new ULine(0, dimensionToUse.getHeight())); + + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 5; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingHeader.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingHeader.java new file mode 100644 index 000000000..80db5db35 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingHeader.java @@ -0,0 +1,148 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4258 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernGroupingHeader extends AbstractTextualComponent { + + private final int cornersize = 10; + private final int commentMargin = 0; // 8; + + private final TextBlock commentTextBlock; + + private final Color headerBackgroundColor; + private final Color generalBackgroundColor; + private final Color borderColor; + + public ComponentBlueModernGroupingHeader(Color headerBackgroundColor, Color generalBackgroundColor, + Color borderColor, Color fontColor1, Color fontColor2, Font bigFont, Font smallFont, + List strings) { + super(strings.get(0), fontColor1, bigFont, HorizontalAlignement.LEFT, 15, 30, 1); + this.headerBackgroundColor = headerBackgroundColor; + this.generalBackgroundColor = generalBackgroundColor; + this.borderColor = borderColor; + if (strings.size() == 1 || strings.get(1) == null) { + this.commentTextBlock = null; + } else { + this.commentTextBlock = TextBlockUtils.create(Arrays.asList("[" + strings.get(1) + "]"), smallFont, + fontColor2, HorizontalAlignement.LEFT); + } + } + + @Override + public double getPaddingY() { + return 6; + } + + @Override + final public double getPreferredWidth(StringBounder stringBounder) { + final double sup; + if (commentTextBlock == null) { + sup = commentMargin * 2; + } else { + final Dimension2D size = commentTextBlock.calculateDimension(stringBounder); + sup = getMarginX1() + commentMargin + size.getWidth(); + + } + return getTextWidth(stringBounder) + sup; + } + + @Override + final public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 2 * getPaddingY(); + } + + @Override + protected void drawBackgroundInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(generalBackgroundColor); + ug.getParam().setBackcolor(generalBackgroundColor); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight())); + } + + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int textWidth = (int) getTextWidth(stringBounder); + final int textHeight = (int) getTextHeight(stringBounder); + + final UPolygon polygon = new UPolygon(); + polygon.addPoint(0, 0); + polygon.addPoint(textWidth, 0); + + polygon.addPoint(textWidth, textHeight - cornersize); + polygon.addPoint(textWidth - cornersize, textHeight); + + polygon.addPoint(0, textHeight); + polygon.addPoint(0, 0); + + ug.getParam().setStroke(new UStroke(2)); + ug.getParam().setBackcolor(headerBackgroundColor); + ug.getParam().setColor(borderColor); + ug.draw(0, 0, polygon); + ug.draw(0, 0, new ULine(dimensionToUse.getWidth(), 0)); + ug.draw(dimensionToUse.getWidth(), 0, new ULine(0, dimensionToUse.getHeight())); + ug.draw(0, textHeight, new ULine(0, dimensionToUse.getHeight()-textHeight)); + ug.getParam().setStroke(new UStroke()); + + getTextBlock().drawU(ug, getMarginX1(), getMarginY()); + + if (commentTextBlock != null) { + //final Dimension2D size = commentTextBlock.calculateDimension(stringBounder); + ug.getParam().setColor(generalBackgroundColor); + final int x1 = getMarginX1() + textWidth; + final int y2 = getMarginY() + 1; + //ug.draw(x1, y2, new URectangle(size.getWidth() + 2 * commentMargin, size.getHeight())); + + commentTextBlock.drawU(ug, x1 + commentMargin, y2); + } + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingTail.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingTail.java new file mode 100644 index 000000000..7adb25051 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernGroupingTail.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernGroupingTail extends AbstractComponent { + + private final Color foregroundColor; + + public ComponentBlueModernGroupingTail(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setStroke(new UStroke(2)); + ug.getParam().setColor(foregroundColor); + + ug.draw(0, dimensionToUse.getHeight(), new ULine(dimensionToUse.getWidth(), 0)); + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 5; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernLine.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernLine.java new file mode 100644 index 000000000..e2fabf046 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernLine.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernLine extends AbstractComponent { + + private final Color color; + + public ComponentBlueModernLine(Color color) { + this.color = color; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(color); + ug.getParam().setBackcolor(color); + final int x = (int) (dimensionToUse.getWidth() / 2); + final StringBounder stringBounder = ug.getStringBounder(); + ug.draw(x, 0, new URectangle(getPreferredWidth(stringBounder), dimensionToUse.getHeight())); + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 20; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 2; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernNewpage.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernNewpage.java new file mode 100644 index 000000000..883778280 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernNewpage.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernNewpage extends AbstractComponent { + + private final Color foregroundColor; + + public ComponentBlueModernNewpage(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + stroke(ug, 10, 2); + ug.getParam().setColor(foregroundColor); + + ug.draw(0, 0, new ULine(dimensionToUse.getWidth(), 0)); + + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 2; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernNote.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernNote.java new file mode 100644 index 000000000..e6b3696d0 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernNote.java @@ -0,0 +1,114 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; + +final public class ComponentBlueModernNote extends AbstractTextualComponent { + + private final int shadowview = 4; + private final int cornersize = 10; + private final Color back; + private final Color foregroundColor; + + public ComponentBlueModernNote(Color back, Color foregroundColor, Color fontColor, Font font, + List strings) { + super(strings, fontColor, font, HorizontalAlignement.LEFT, 6, 15, 5); + this.back = back; + this.foregroundColor = foregroundColor; + } + + @Override + final public double getPreferredWidth(StringBounder stringBounder) { + final double result = getTextWidth(stringBounder) + 2 * getPaddingX(); + return result; + } + + @Override + final public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 2 * getPaddingY(); + } + + @Override + public double getPaddingX() { + return 9; + } + + @Override + public double getPaddingY() { + return 9; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final double textHeight = getTextHeight(stringBounder); + + final double textWidth = getTextWidth(stringBounder); + + final ShadowShape shadowShape = new ShadowShape(textWidth, textHeight, 3); + ug.translate(shadowview, shadowview); + shadowShape.drawU(ug); + ug.translate(-shadowview, -shadowview); + + final UPolygon polygon = new UPolygon(); + polygon.addPoint(0, 0); + polygon.addPoint(0, textHeight); + polygon.addPoint(textWidth, textHeight); + polygon.addPoint(textWidth, cornersize); + polygon.addPoint(textWidth - cornersize, 0); + polygon.addPoint(0, 0); + + ug.getParam().setBackcolor(back); + ug.getParam().setColor(foregroundColor); + ug.draw(0, 0, polygon); + + ug.draw(textWidth - cornersize, 0, new ULine(0, cornersize)); + ug.draw(textWidth, cornersize, new ULine(-cornersize, 0)); + + getTextBlock().drawU(ug, getMarginX1(), getMarginY()); + + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernParticipant.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernParticipant.java new file mode 100644 index 000000000..762e770a5 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernParticipant.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4738 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ComponentBlueModernParticipant extends AbstractTextualComponent { + + private final int shadowview = 3; + private final Color blue1; + private final Color blue2; + + public ComponentBlueModernParticipant(Color blue1, Color blue2, Color fontColor, Font font, + List stringsToDisplay) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.CENTER, 7, 7, 7); + this.blue1 = blue1; + this.blue2 = blue2; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + + final ShadowShape shadowShape = new ShadowShape(getTextWidth(stringBounder), getTextHeight(stringBounder), 10); + ug.translate(shadowview, shadowview); + shadowShape.drawU(ug); + ug.translate(-shadowview, -shadowview); + + final FillRoundShape shape = new FillRoundShape(getTextWidth(stringBounder), getTextHeight(stringBounder), + blue1, blue2, 10); + shape.drawU(ug); + + getTextBlock().drawU(ug, getMarginX1(), getMarginY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + shadowview; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernSelfArrow.java b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernSelfArrow.java new file mode 100644 index 000000000..1697eed82 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ComponentBlueModernSelfArrow.java @@ -0,0 +1,115 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4634 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentBlueModernSelfArrow extends AbstractComponentBlueModernArrow { + + private final double arrowWidth = 45; + + public ComponentBlueModernSelfArrow(Color foregroundColor, Color colorFont, Font font, + List stringsToDisplay, boolean dotted, boolean full) { + super(foregroundColor, colorFont, font, stringsToDisplay, dotted, full); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int textHeight = (int) getTextHeight(stringBounder); + + ug.getParam().setBackcolor(getForegroundColor()); + ug.getParam().setColor(getForegroundColor()); + final int x2 = (int) arrowWidth; + + if (isDotted()) { + stroke(ug, 5, 2); + } else { + ug.getParam().setStroke(new UStroke(2)); + } + + ug.draw(0, textHeight, new ULine(x2, 0)); + + final int textAndArrowHeight = (int) (textHeight + getArrowOnlyHeight(stringBounder)); + + ug.draw(x2, textHeight, new ULine(0, textAndArrowHeight - textHeight)); + ug.draw(x2, textAndArrowHeight, new ULine(2 - x2, 0)); + + ug.getParam().setStroke(new UStroke()); + + final int delta = (int) getArrowOnlyHeight(stringBounder); + + if (isFull()) { + final UPolygon polygon = new UPolygon(); + polygon.addPoint(getArrowDeltaX(), textHeight - getArrowDeltaY() + delta); + polygon.addPoint(0, textHeight + delta); + polygon.addPoint(getArrowDeltaX(), textHeight + getArrowDeltaY() + delta); + ug.draw(0, 0, polygon); + } else { + ug.getParam().setStroke(new UStroke(1.5)); + ug.draw(getArrowDeltaX2(), textHeight - getArrowDeltaY2() + delta, new ULine(-getArrowDeltaX2(), + getArrowDeltaY2())); + ug.draw(getArrowDeltaX2(), textHeight + getArrowDeltaY2() + delta, new ULine(-getArrowDeltaX2(), + -getArrowDeltaY2())); + ug.getParam().setStroke(new UStroke()); + } + + getTextBlock().drawU(ug, getMarginX1(), 0); + + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + getArrowDeltaY() + getArrowOnlyHeight(stringBounder) + 2 * getPaddingY(); + } + + private double getArrowOnlyHeight(StringBounder stringBounder) { + return 13; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return Math.max(getTextWidth(stringBounder), arrowWidth); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/FillRoundShape.java b/src/net/sourceforge/plantuml/skin/bluemodern/FillRoundShape.java new file mode 100644 index 000000000..76fe10576 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/FillRoundShape.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3914 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.geom.RoundRectangle2D; + +import net.sourceforge.plantuml.ugraphic.UGradient; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class FillRoundShape { + + final private double width; + final private double height; + final private double corner; + final private Color c1; + final private Color c2; + + public FillRoundShape(double width, double height, Color c1, Color c2, double corner) { + this.width = width; + this.height = height; + this.c1 = c1; + this.c2 = c2; + this.corner = corner; + + } + + public void draw(Graphics2D g2d) { + final GradientPaint paint = new GradientPaint(0, 0, c1, (float) width, (float) height, c2); + final RoundRectangle2D r = new RoundRectangle2D.Double(0, 0, width, height, corner * 2, corner * 2); + g2d.setPaint(paint); + g2d.fill(r); + } + + public void drawU(UGraphic ug) { + final UGradient gradient = new UGradient(c1, c2); + final URectangle r = new URectangle(width, height, corner * 2, corner * 2); + ug.getParam().setGradient(gradient); + ug.draw(0, 0, r); + ug.getParam().setGradient(null); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/ShadowShape.java b/src/net/sourceforge/plantuml/skin/bluemodern/ShadowShape.java new file mode 100644 index 000000000..7fc3ea595 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/bluemodern/ShadowShape.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.skin.bluemodern; + +import java.awt.Color; + +public class ShadowShape extends FillRoundShape { + + public ShadowShape(double width, double height, double corner) { + super(width, height, Color.LIGHT_GRAY, Color.GRAY, corner); + + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/AbstractComponentRoseArrow.java b/src/net/sourceforge/plantuml/skin/rose/AbstractComponentRoseArrow.java new file mode 100644 index 000000000..c7b956e22 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/AbstractComponentRoseArrow.java @@ -0,0 +1,85 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4631 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.skin.ArrowComponent; + +public abstract class AbstractComponentRoseArrow extends AbstractTextualComponent implements ArrowComponent { + + private final int arrowDeltaX = 10; + private final int arrowDeltaY = 4; + private final boolean dotted; + private final boolean full; + private final Color foregroundColor; + + public AbstractComponentRoseArrow(Color foregroundColor, Color fontColor, Font font, + List stringsToDisplay, boolean dotted, boolean full) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.LEFT, 7, 7, 2); + this.dotted = dotted; + this.full = full; + this.foregroundColor = foregroundColor; + } + + protected final Color getForegroundColor() { + return foregroundColor; + } + + final protected int getArrowDeltaX() { + return arrowDeltaX; + } + + final protected int getArrowDeltaY() { + return arrowDeltaY; + } + + @Override + public final double getPaddingY() { + return 6; + } + + final protected boolean isDotted() { + return dotted; + } + + final protected boolean isFull() { + return full; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseActiveLine.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseActiveLine.java new file mode 100644 index 000000000..eec8b1817 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseActiveLine.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class ComponentRoseActiveLine extends AbstractComponent { + + private final Color foregroundColor; + private final Color lifeLineBackground; + + public ComponentRoseActiveLine(Color foregroundColor, Color lifeLineBackground) { + this.foregroundColor = foregroundColor; + this.lifeLineBackground = lifeLineBackground; + } + + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setBackcolor(lifeLineBackground); + ug.getParam().setColor(foregroundColor); + final StringBounder stringBounder = ug.getStringBounder(); + final int x = (int) (dimensionToUse.getWidth() - getPreferredWidth(stringBounder)) / 2; + + final URectangle rect = new URectangle(getPreferredWidth(stringBounder), dimensionToUse.getHeight()); + ug.draw(x, 0, rect); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 0; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 10; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseActor.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseActor.java new file mode 100644 index 000000000..5ae8b45af --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseActor.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4738 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.skin.StickMan; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ComponentRoseActor extends AbstractTextualComponent { + + private final StickMan stickman; + private final boolean head; + + public ComponentRoseActor(Color yellow, Color red, Color fontColor, Font font, + List stringsToDisplay, boolean head) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.LEFT, 3, 3, 0); + this.head = head; + stickman = new StickMan(yellow, red); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(getFontColor()); + final TextBlock textBlock = getTextBlock(); + final StringBounder stringBounder = ug.getStringBounder(); + final double delta = (getPreferredWidth(stringBounder) - stickman.getPreferredWidth(stringBounder)) / 2; + + if (head) { + textBlock.drawU(ug, getTextMiddlePostion(stringBounder), stickman.getPreferredHeight(stringBounder)); + ug.translate(delta, 0); + } else { + textBlock.drawU(ug, getTextMiddlePostion(stringBounder), 0); + ug.translate(delta, getTextHeight(stringBounder)); + } + stickman.drawU(ug); + } + + private double getTextMiddlePostion(StringBounder stringBounder) { + return (getPreferredWidth(stringBounder) - getTextWidth(stringBounder)) / 2.0; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return stickman.getPreferredHeight(stringBounder) + getTextHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return Math.max(stickman.getPreferredWidth(stringBounder), getTextWidth(stringBounder)); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseArrow.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseArrow.java new file mode 100644 index 000000000..d1135ac52 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseArrow.java @@ -0,0 +1,139 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4632 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseArrow extends AbstractComponentRoseArrow { + + private final int direction; + + public ComponentRoseArrow(Color foregroundColor, Color fontColor, Font font, + List stringsToDisplay, int direction, boolean dotted, boolean full) { + super(foregroundColor, fontColor, font, stringsToDisplay, dotted, full); + this.direction = direction; + if (direction != 1 && direction != -1) { + throw new IllegalArgumentException(); + } + } + + @Override + public void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int textHeight = (int) getTextHeight(stringBounder); + ug.getParam().setColor(getForegroundColor()); + + final int x2 = (int) dimensionToUse.getWidth(); + + if (isDotted()) { + stroke(ug, 2); + } + + // + ug.draw(0, textHeight, new ULine(x2, 0)); + if (isDotted()) { + ug.getParam().setStroke(new UStroke()); + } + final int direction = getDirection(); + if (direction == 1) { + if (isFull()) { + ug.getParam().setBackcolor(getForegroundColor()); + final UPolygon polygon = new UPolygon(); + polygon.addPoint(x2 - getArrowDeltaX(), textHeight - getArrowDeltaY()); + polygon.addPoint(x2, textHeight); + polygon.addPoint(x2 - getArrowDeltaX(), textHeight + getArrowDeltaY()); + ug.draw(0, 0, polygon); + ug.getParam().setBackcolor(null); + } else { + ug.draw(x2, textHeight, new ULine(-getArrowDeltaX(), -getArrowDeltaY())); + ug.draw(x2, textHeight, new ULine(-getArrowDeltaX(), getArrowDeltaY())); + } + } else { + if (isFull()) { + ug.getParam().setBackcolor(getForegroundColor()); + final UPolygon polygon = new UPolygon(); + polygon.addPoint(getArrowDeltaX(), textHeight - getArrowDeltaY()); + polygon.addPoint(0, textHeight); + polygon.addPoint(getArrowDeltaX(), textHeight + getArrowDeltaY()); + ug.draw(0, 0, polygon); + ug.getParam().setBackcolor(null); + } else { + ug.draw(0, textHeight, new ULine(getArrowDeltaX(), -getArrowDeltaY())); + ug.draw(0, textHeight, new ULine(getArrowDeltaX(), getArrowDeltaY())); + } + } + getTextBlock().drawU(ug, getMarginX1(), 0); + } + + public Point2D getStartPoint(StringBounder stringBounder, Dimension2D dimensionToUse) { + final int textHeight = (int) getTextHeight(stringBounder); + if (direction == 1) { + return new Point2D.Double(getPaddingX(), textHeight + getPaddingY()); + } + return new Point2D.Double(dimensionToUse.getWidth() + getPaddingX(), textHeight + getPaddingY()); + } + + public Point2D getEndPoint(StringBounder stringBounder, Dimension2D dimensionToUse) { + final int textHeight = (int) getTextHeight(stringBounder); + if (direction == 1) { + return new Point2D.Double(dimensionToUse.getWidth() + getPaddingX(), textHeight + getPaddingY()); + } + return new Point2D.Double(getPaddingX(), textHeight + getPaddingY()); + } + + final protected int getDirection() { + return direction; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + getArrowDeltaY() + 2 * getPaddingY(); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDestroy.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDestroy.java new file mode 100644 index 000000000..79998d5dc --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDestroy.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4169 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseDestroy extends AbstractComponent { + + private final Color foregroundColor; + + public ComponentRoseDestroy(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + private final int crossSize = 9; + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setStroke(new UStroke(2)); + + ug.getParam().setColor(foregroundColor); + ug.draw(0, 0, new ULine(2 * crossSize, 2 * crossSize)); + ug.draw(0, 2 * crossSize, new ULine(2 * crossSize, -2 * crossSize)); + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return crossSize * 2; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return crossSize * 2; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDivider.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDivider.java new file mode 100644 index 000000000..2fdd2a4bc --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseDivider.java @@ -0,0 +1,96 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseDivider extends AbstractTextualComponent { + + // private final int outMargin = 5; + private final Color background; + + public ComponentRoseDivider(Color fontColor, Font font, Color background, + List stringsToDisplay) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.CENTER, 4, 4, 4); + this.background = background; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final TextBlock textBlock = getTextBlock(); + final StringBounder stringBounder = ug.getStringBounder(); + final double textWidth = getTextWidth(stringBounder); + final double textHeight = getTextHeight(stringBounder); + + final double deltaX = 6; + final double xpos = (dimensionToUse.getWidth() - textWidth - deltaX) / 2; + final double ypos = (dimensionToUse.getHeight() - textHeight) / 2; + + ug.getParam().setColor(Color.BLACK); + ug.draw(0, dimensionToUse.getHeight() / 2 - 1, new ULine(dimensionToUse.getWidth(), 0)); + ug.draw(0, dimensionToUse.getHeight() / 2 + 2, new ULine(dimensionToUse.getWidth(), 0)); + + ug.getParam().setColor(Color.BLACK); + ug.getParam().setBackcolor(background); + + ug.getParam().setStroke(new UStroke(2)); + ug.draw(xpos, ypos, new URectangle(textWidth + deltaX, textHeight)); + ug.getParam().setStroke(new UStroke()); + + textBlock.drawU(ug, xpos + deltaX, ypos + getMarginY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 20; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder) + 30; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseEnglober.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseEnglober.java new file mode 100644 index 000000000..bd7578efd --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseEnglober.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4258 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class ComponentRoseEnglober extends AbstractTextualComponent { + + private final Color borderColor; + private final Color backColor; + + public ComponentRoseEnglober(Color borderColor, Color backColor, List strings, Color fontColor, Font font) { + super(strings, fontColor, font, HorizontalAlignement.CENTER, 3, 3, 1); + this.borderColor = borderColor; + this.backColor = backColor; + } + + @Override + protected void drawBackgroundInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(borderColor); + ug.getParam().setBackcolor(backColor); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse.getHeight())); + final double xpos = (dimensionToUse.getWidth() - getPureTextWidth(ug.getStringBounder())) / 2; + getTextBlock().drawU(ug, xpos, 0); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + // ug.getParam().setColor(Color.RED); + // ug.getParam().setBackcolor(Color.YELLOW); + // ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), + // dimensionToUse.getHeight())); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 3; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder); + } +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingBody.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingBody.java new file mode 100644 index 000000000..ecca2cf64 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingBody.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4258 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseGroupingBody extends AbstractComponent { + + private final Color foregroundColor; + private final Color background; + + public ComponentRoseGroupingBody(Color background, Color foregroundColor) { + this.foregroundColor = foregroundColor; + this.background = background; + + } + + @Override + protected void drawBackgroundInternalU(UGraphic ug, + Dimension2D dimensionToUse) { + if (this.background == null) { + return; + } + ug.getParam().setColor(null); + ug.getParam().setBackcolor(background); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse + .getHeight())); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setStroke(new UStroke(2)); + ug.getParam().setColor(foregroundColor); + + ug.draw(0, 0, new ULine(0, dimensionToUse.getHeight())); + ug.draw(dimensionToUse.getWidth(), 0, new ULine(0, dimensionToUse + .getHeight())); + + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 5; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingElse.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingElse.java new file mode 100644 index 000000000..13646a04a --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingElse.java @@ -0,0 +1,73 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4258 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseGroupingElse extends AbstractTextualComponent { + + public ComponentRoseGroupingElse(Color fontColor, Font smallFont, CharSequence comment) { + super(comment == null ? null : "[" + comment + "]", fontColor, smallFont, HorizontalAlignement.LEFT, 5, 5, 1); + } + + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + stroke(ug, 2); + ug.getParam().setColor(getFontColor()); + ug.draw(0, 1, new ULine(dimensionToUse.getWidth(), 0)); + ug.getParam().setStroke(new UStroke()); + getTextBlock().drawU(ug, getMarginX1(), getMarginY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 15; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingHeader.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingHeader.java new file mode 100644 index 000000000..58ee2e0c1 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingHeader.java @@ -0,0 +1,157 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4258 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseGroupingHeader extends AbstractTextualComponent { + + private final int cornersize = 10; + private final int commentMargin = 0; // 8; + + private final TextBlock commentTextBlock; + + private final Color groupBackground; + private final Color background; + + public ComponentRoseGroupingHeader(Color fontColor, Color background, + Color groupBackground, Font bigFont, Font smallFont, + List strings) { + super(strings.get(0), fontColor, bigFont, HorizontalAlignement.LEFT, + 15, 30, 1); + this.groupBackground = groupBackground; + this.background = background; + if (strings.size() == 1 || strings.get(1) == null) { + this.commentTextBlock = null; + } else { + this.commentTextBlock = TextBlockUtils.create(Arrays.asList("[" + + strings.get(1) + "]"), smallFont, fontColor, + HorizontalAlignement.LEFT); + } + } + + @Override + public double getPaddingY() { + return 6; + } + + @Override + final public double getPreferredWidth(StringBounder stringBounder) { + final double sup; + if (commentTextBlock == null) { + sup = commentMargin * 2; + } else { + final Dimension2D size = commentTextBlock + .calculateDimension(stringBounder); + sup = getMarginX1() + commentMargin + size.getWidth(); + + } + return getTextWidth(stringBounder) + sup; + } + + @Override + final public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 2 * getPaddingY(); + } + + @Override + protected void drawBackgroundInternalU(UGraphic ug, + Dimension2D dimensionToUse) { + if (this.background == null) { + return; + } + ug.getParam().setColor(null); + ug.getParam().setBackcolor(background); + ug.draw(0, 0, new URectangle(dimensionToUse.getWidth(), dimensionToUse + .getHeight())); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int textWidth = (int) getTextWidth(stringBounder); + final int textHeight = (int) getTextHeight(stringBounder); + + final UPolygon polygon = new UPolygon(); + polygon.addPoint(0, 0); + polygon.addPoint(textWidth, 0); + + polygon.addPoint(textWidth, textHeight - cornersize); + polygon.addPoint(textWidth - cornersize, textHeight); + + polygon.addPoint(0, textHeight); + polygon.addPoint(0, 0); + + ug.getParam().setStroke(new UStroke(2)); + ug.getParam().setColor(getFontColor()); + ug.getParam().setBackcolor(this.groupBackground); + ug.draw(0, 0, polygon); + + ug.draw(0, 0, new ULine(dimensionToUse.getWidth(), 0)); + ug.draw(dimensionToUse.getWidth(), 0, new ULine(0, dimensionToUse.getHeight())); + ug.draw(0, textHeight, new ULine(0, dimensionToUse.getHeight()-textHeight)); + ug.getParam().setStroke(new UStroke()); + + getTextBlock().drawU(ug, getMarginX1(), getMarginY()); + + if (commentTextBlock != null) { + // final Dimension2D size = + // commentTextBlock.calculateDimension(stringBounder); + // ug.getParam().setColor(null/*this.background*/); + // ug.getParam().setBackcolor(null); + final int x1 = getMarginX1() + textWidth; + final int y2 = getMarginY() + 1; + // ug.draw(x1, y2, new URectangle(size.getWidth() + 2 * + // commentMargin, size.getHeight())); + + commentTextBlock.drawU(ug, x1 + commentMargin, y2); + } + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingTail.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingTail.java new file mode 100644 index 000000000..009be0013 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseGroupingTail.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5528 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseGroupingTail extends AbstractComponent { + + private final Color foregroundColor; + + public ComponentRoseGroupingTail(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setStroke(new UStroke(2)); + ug.getParam().setColor(foregroundColor); + ug.draw(0, dimensionToUse.getHeight(), new ULine(dimensionToUse.getWidth(), 0)); + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 6; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseLine.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseLine.java new file mode 100644 index 000000000..c052531ae --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseLine.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseLine extends AbstractComponent { + + private final Color color; + + public ComponentRoseLine(Color color) { + this.color = color; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + ug.getParam().setColor(color); + stroke(ug, 5); + final int x = (int) (dimensionToUse.getWidth() / 2); + ug.draw(x, 0, new ULine(0, dimensionToUse.getHeight())); + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 20; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNewpage.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNewpage.java new file mode 100644 index 000000000..89303ff1a --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNewpage.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseNewpage extends AbstractComponent { + + private final Color foregroundColor; + + public ComponentRoseNewpage(Color foregroundColor) { + this.foregroundColor = foregroundColor; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + stroke(ug, 2); + ug.getParam().setColor(foregroundColor); + ug.draw(0, 0, new ULine(dimensionToUse.getWidth(), 0)); + ug.getParam().setStroke(new UStroke()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return 1; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return 0; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java new file mode 100644 index 000000000..0f81fe149 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java @@ -0,0 +1,108 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; + +final public class ComponentRoseNote extends AbstractTextualComponent { + + private final int cornersize = 10; + private final Color back; + private final Color foregroundColor; + + public ComponentRoseNote(Color back, Color foregroundColor, Color fontColor, Font font, + List strings) { + super(strings, fontColor, font, HorizontalAlignement.LEFT, 6, 15, 5); + this.back = back; + this.foregroundColor = foregroundColor; + } + + @Override + final public double getPreferredWidth(StringBounder stringBounder) { + final double result = getTextWidth(stringBounder) + 2 * getPaddingX(); + return result; + } + + @Override + final public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + 2 * getPaddingY(); + } + + @Override + public double getPaddingX() { + return 5; + } + + @Override + public double getPaddingY() { + return 5; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final int textHeight = (int) getTextHeight(stringBounder); + + final int x2 = (int) getTextWidth(stringBounder); + + final UPolygon polygon = new UPolygon(); + polygon.addPoint(0, 0); + polygon.addPoint(0, textHeight); + polygon.addPoint(x2, textHeight); + polygon.addPoint(x2, cornersize); + polygon.addPoint(x2 - cornersize, 0); + polygon.addPoint(0, 0); + + ug.getParam().setColor(foregroundColor); + ug.getParam().setBackcolor(back); + ug.draw(0, 0, polygon); + + ug.draw(x2 - cornersize, 0, new ULine(0, cornersize)); + ug.draw(x2, cornersize, new ULine(-cornersize, 0)); + + getTextBlock().drawU(ug, getMarginX1(), getMarginY()); + + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseParticipant.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseParticipant.java new file mode 100644 index 000000000..39527e4b5 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseParticipant.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4738 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.URectangle; + +public class ComponentRoseParticipant extends AbstractTextualComponent { + + private final Color back; + private final Color foregroundColor; + + public ComponentRoseParticipant(Color back, Color foregroundColor, Color fontColor, Font font, + List stringsToDisplay) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.CENTER, 7, 7, 7); + this.back = back; + this.foregroundColor = foregroundColor; + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + ug.getParam().setColor(foregroundColor); + ug.getParam().setBackcolor(back); + ug.draw(0, 0, new URectangle(getTextWidth(stringBounder), getTextHeight(stringBounder))); + final TextBlock textBlock = getTextBlock(); + textBlock.drawU(ug, getMarginX1(), getMarginY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java new file mode 100644 index 000000000..24a5def2e --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseSelfArrow.java @@ -0,0 +1,123 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4633 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class ComponentRoseSelfArrow extends AbstractComponentRoseArrow { + + private final double arrowWidth = 45; + + public ComponentRoseSelfArrow(Color foregroundColor, Color colorFont, Font font, + List stringsToDisplay, boolean dotted, boolean full) { + super(foregroundColor, colorFont, font, stringsToDisplay, dotted, full); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final StringBounder stringBounder = ug.getStringBounder(); + final double textHeight = getTextHeight(stringBounder); + + ug.getParam().setColor(getForegroundColor()); + final double x2 = arrowWidth; + + if (isDotted()) { + stroke(ug, 2); + } + + ug.draw(0, textHeight, new ULine(x2, 0)); + + final double textAndArrowHeight = textHeight + getArrowOnlyHeight(stringBounder); + + ug.draw(x2, textHeight, new ULine(0, textAndArrowHeight - textHeight)); + ug.draw(0, textAndArrowHeight, new ULine(x2, 0)); + + if (isDotted()) { + ug.getParam().setStroke(new UStroke()); + } + +// ug.draw(0, textAndArrowHeight, new ULine(getArrowDeltaX(), -getArrowDeltaY())); +// ug.draw(0, textAndArrowHeight, new ULine(getArrowDeltaX(), getArrowDeltaY())); + if (isFull()) { + ug.getParam().setBackcolor(getForegroundColor()); + final UPolygon polygon = new UPolygon(); + polygon.addPoint(getArrowDeltaX(), textAndArrowHeight - getArrowDeltaY()); + polygon.addPoint(0, textAndArrowHeight); + polygon.addPoint(getArrowDeltaX(), textAndArrowHeight + getArrowDeltaY()); + ug.draw(0, 0, polygon); + ug.getParam().setBackcolor(null); + } else { + ug.draw(0, textHeight, new ULine(getArrowDeltaX(), -getArrowDeltaY())); + ug.draw(0, textHeight, new ULine(getArrowDeltaX(), getArrowDeltaY())); + } + + getTextBlock().drawU(ug, getMarginX1(), 0); + } + + public Point2D getStartPoint(StringBounder stringBounder, Dimension2D dimensionToUse) { + final int textHeight = (int) getTextHeight(stringBounder); + return new Point2D.Double(getPaddingX(), textHeight + getPaddingY()); + } + + public Point2D getEndPoint(StringBounder stringBounder, Dimension2D dimensionToUse) { + final int textHeight = (int) getTextHeight(stringBounder); + final int textAndArrowHeight = (int) (textHeight + getArrowOnlyHeight(stringBounder)); + return new Point2D.Double(getPaddingX(), textAndArrowHeight + getPaddingY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder) + getArrowDeltaY() + getArrowOnlyHeight(stringBounder) + 2 * getPaddingY(); + } + + private double getArrowOnlyHeight(StringBounder stringBounder) { + return 13; + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return Math.max(getTextWidth(stringBounder), arrowWidth); + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseTitle.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseTitle.java new file mode 100644 index 000000000..10af118d5 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseTitle.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4167 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.util.List; + +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.AbstractTextualComponent; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ComponentRoseTitle extends AbstractTextualComponent { + + private final int outMargin = 5; + + public ComponentRoseTitle(Color fontColor, Font font, List stringsToDisplay) { + super(stringsToDisplay, fontColor, font, HorizontalAlignement.CENTER, 7, 7, 7); + } + + @Override + protected void drawInternalU(UGraphic ug, Dimension2D dimensionToUse) { + final TextBlock textBlock = getTextBlock(); + textBlock.drawU(ug, outMargin + getMarginX1(), getMarginY()); + } + + @Override + public double getPreferredHeight(StringBounder stringBounder) { + return getTextHeight(stringBounder); + } + + @Override + public double getPreferredWidth(StringBounder stringBounder) { + return getTextWidth(stringBounder) + outMargin * 2; + } + +} diff --git a/src/net/sourceforge/plantuml/skin/rose/Rose.java b/src/net/sourceforge/plantuml/skin/rose/Rose.java new file mode 100644 index 000000000..e1f5e4a59 --- /dev/null +++ b/src/net/sourceforge/plantuml/skin/rose/Rose.java @@ -0,0 +1,282 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5218 $ + * + */ +package net.sourceforge.plantuml.skin.rose; + +import java.awt.Color; +import java.awt.Font; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Skin; + +public class Rose implements Skin { + + private final Map defaultsColor = new EnumMap(ColorParam.class); + + public Rose() { + defaultsColor.put(ColorParam.background, new HtmlColor("white")); + + defaultsColor.put(ColorParam.sequenceArrow, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.usecaseArrow, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.classArrow, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.objectArrow, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.activityArrow, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.componentArrow, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.stateArrow, new HtmlColor("#A80036")); + + defaultsColor.put(ColorParam.sequenceLifeLineBackground, new HtmlColor("white")); + defaultsColor.put(ColorParam.sequenceLifeLineBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.sequenceGroupBackground, new HtmlColor("#EEEEEE")); + defaultsColor.put(ColorParam.sequenceDividerBackground, new HtmlColor("#EEEEEE")); + defaultsColor.put(ColorParam.sequenceEngloberLine, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.sequenceEngloberBackground, new HtmlColor("#DDDDDD")); + + defaultsColor.put(ColorParam.noteBackground, new HtmlColor("#FBFB77")); + defaultsColor.put(ColorParam.noteBorder, new HtmlColor("#A80036")); + + defaultsColor.put(ColorParam.activityBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.activityBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.activityStart, new HtmlColor("black")); + defaultsColor.put(ColorParam.activityEnd, new HtmlColor("black")); + defaultsColor.put(ColorParam.activityBar, new HtmlColor("black")); + + defaultsColor.put(ColorParam.stateBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.stateBorder, new HtmlColor("#A80036")); + + defaultsColor.put(ColorParam.usecaseBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.usecaseBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.componentBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.componentBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.interfaceBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.interfaceBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.actorBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.actorBorder, new HtmlColor("#A80036")); + + defaultsColor.put(ColorParam.sequenceActorBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.sequenceActorBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.sequenceParticipantBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.sequenceParticipantBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.classBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.classBorder, new HtmlColor("#A80036")); + + defaultsColor.put(ColorParam.objectBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.objectBorder, new HtmlColor("#A80036")); + + defaultsColor.put(ColorParam.stereotypeCBackground, new HtmlColor("#ADD1B2")); + defaultsColor.put(ColorParam.stereotypeABackground, new HtmlColor("#A9DCDF")); + defaultsColor.put(ColorParam.stereotypeIBackground, new HtmlColor("#B4A7E5")); + defaultsColor.put(ColorParam.stereotypeEBackground, new HtmlColor("#EB937F")); + + defaultsColor.put(ColorParam.packageBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.packageBorder, new HtmlColor("black")); + + defaultsColor.put(ColorParam.iconPrivate, new HtmlColor("#C82930")); + defaultsColor.put(ColorParam.iconPrivateBackground, new HtmlColor("#F24D5C")); + defaultsColor.put(ColorParam.iconProtected, new HtmlColor("#B38D22")); + defaultsColor.put(ColorParam.iconProtectedBackground, new HtmlColor("#FFFF44")); + defaultsColor.put(ColorParam.iconPackage, new HtmlColor("#1963A0")); + defaultsColor.put(ColorParam.iconPackageBackground, new HtmlColor("#4177AF")); + defaultsColor.put(ColorParam.iconPublic, new HtmlColor("#038048")); + defaultsColor.put(ColorParam.iconPublicBackground, new HtmlColor("#84BE84")); + } + + public Color getFontColor(ISkinParam skin, FontParam fontParam) { + return skin.getFontHtmlColor(fontParam).getColor(); + } + + public HtmlColor getHtmlColor(ISkinParam param, ColorParam color) { + HtmlColor result = param.getHtmlColor(color); + if (result == null) { + result = defaultsColor.get(color); + if (result == null) { + throw new IllegalArgumentException(); + } + } + return result; + } + + public Component createComponent(ComponentType type, ISkinParam param, List stringsToDisplay) { + final Color background = param.getBackgroundColor().getColor(); + final Color groundBackgroundColor = getHtmlColor(param, ColorParam.sequenceGroupBackground).getColor(); + final Color sequenceDividerBackground = getHtmlColor(param, ColorParam.sequenceDividerBackground).getColor(); + final Color lifeLineBackgroundColor = getHtmlColor(param, ColorParam.sequenceLifeLineBackground).getColor(); + final Color sequenceArrow = getHtmlColor(param, ColorParam.sequenceArrow).getColor(); + final Color sequenceActorBackground = getHtmlColor(param, ColorParam.sequenceActorBackground).getColor(); + final Color sequenceParticipantBackground = getHtmlColor(param, ColorParam.sequenceParticipantBackground) + .getColor(); + // final Color borderColor = getHtmlColor(param, + // ColorParam.border).getColor(); + + final Font fontArrow = param.getFont(FontParam.SEQUENCE_ARROW); + final Font fontGrouping = param.getFont(FontParam.SEQUENCE_GROUPING); + final Font fontParticipant = param.getFont(FontParam.SEQUENCE_PARTICIPANT); + final Font fontActor = param.getFont(FontParam.SEQUENCE_ACTOR); + + if (type == ComponentType.SELF_ARROW) { + return new ComponentRoseSelfArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, false, true); + } + if (type == ComponentType.DOTTED_SELF_ARROW) { + return new ComponentRoseSelfArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, true, true); + } + if (type == ComponentType.ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, 1, false, true); + } + if (type == ComponentType.ASYNC_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, 1, false, false); + } + + if (type == ComponentType.RETURN_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, -1, false, true); + } + if (type == ComponentType.ASYNC_RETURN_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, -1, false, false); + } + if (type == ComponentType.DOTTED_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, 1, true, true); + } + if (type == ComponentType.ASYNC_DOTTED_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, 1, true, false); + } + if (type == ComponentType.RETURN_DOTTED_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, -1, true, true); + } + if (type == ComponentType.ASYNC_RETURN_DOTTED_ARROW) { + return new ComponentRoseArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, + stringsToDisplay, -1, true, false); + } + + if (type == ComponentType.PARTICIPANT_HEAD) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceParticipantBorder).getColor(); + return new ComponentRoseParticipant(sequenceParticipantBackground, borderColor, getFontColor(param, + FontParam.SEQUENCE_PARTICIPANT), fontParticipant, stringsToDisplay); + } + if (type == ComponentType.PARTICIPANT_TAIL) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceParticipantBorder).getColor(); + return new ComponentRoseParticipant(sequenceParticipantBackground, borderColor, getFontColor(param, + FontParam.SEQUENCE_PARTICIPANT), fontParticipant, stringsToDisplay); + } + if (type == ComponentType.PARTICIPANT_LINE) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceLifeLineBorder).getColor(); + return new ComponentRoseLine(borderColor); + } + if (type == ComponentType.ACTOR_HEAD) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceActorBorder).getColor(); + return new ComponentRoseActor(sequenceActorBackground, borderColor, getFontColor(param, + FontParam.SEQUENCE_ACTOR), fontActor, stringsToDisplay, true); + } + if (type == ComponentType.ACTOR_TAIL) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceActorBorder).getColor(); + return new ComponentRoseActor(sequenceActorBackground, borderColor, getFontColor(param, + FontParam.SEQUENCE_ACTOR), fontActor, stringsToDisplay, false); + } + if (type == ComponentType.ACTOR_LINE) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceLifeLineBorder).getColor(); + return new ComponentRoseLine(borderColor); + } + if (type == ComponentType.NOTE) { + final Color noteBackgroundColor = getHtmlColor(param, ColorParam.noteBackground).getColor(); + final Color borderColor = getHtmlColor(param, ColorParam.noteBorder).getColor(); + final Font fontNote = param.getFont(FontParam.NOTE); + return new ComponentRoseNote(noteBackgroundColor, borderColor, getFontColor(param, FontParam.NOTE), + fontNote, stringsToDisplay); + } + if (type == ComponentType.GROUPING_HEADER) { + final Font fontGroupingHeader = param.getFont(FontParam.SEQUENCE_GROUPING_HEADER); + return new ComponentRoseGroupingHeader(getFontColor(param, FontParam.SEQUENCE_GROUPING_HEADER), background, + groundBackgroundColor, fontGroupingHeader, fontGrouping, stringsToDisplay); + } + if (type == ComponentType.GROUPING_BODY) { + return new ComponentRoseGroupingBody(background, getFontColor(param, FontParam.SEQUENCE_GROUPING)); + } + if (type == ComponentType.GROUPING_TAIL) { + return new ComponentRoseGroupingTail(getFontColor(param, FontParam.SEQUENCE_GROUPING)); + } + if (type == ComponentType.GROUPING_ELSE) { + return new ComponentRoseGroupingElse(getFontColor(param, FontParam.SEQUENCE_GROUPING), fontGrouping, + stringsToDisplay.get(0)); + } + if (type == ComponentType.ALIVE_LINE) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceLifeLineBorder).getColor(); + return new ComponentRoseActiveLine(borderColor, lifeLineBackgroundColor); + } + if (type == ComponentType.DESTROY) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceLifeLineBorder).getColor(); + return new ComponentRoseDestroy(borderColor); + } + if (type == ComponentType.NEWPAGE) { + return new ComponentRoseNewpage(getFontColor(param, FontParam.SEQUENCE_GROUPING)); + } + if (type == ComponentType.DIVIDER) { + return new ComponentRoseDivider(getFontColor(param, FontParam.SEQUENCE_DIVIDER), param + .getFont(FontParam.SEQUENCE_DIVIDER), sequenceDividerBackground, stringsToDisplay); + } + if (type == ComponentType.TITLE) { + return new ComponentRoseTitle(getFontColor(param, FontParam.SEQUENCE_TITLE), param + .getFont(FontParam.SEQUENCE_TITLE), stringsToDisplay); + } + if (type == ComponentType.SIGNATURE) { + return new ComponentRoseTitle(Color.BLACK, fontGrouping, Arrays.asList("This skin was created ", + "in April 2009.")); + } + if (type == ComponentType.ENGLOBER) { + final Color borderColor = getHtmlColor(param, ColorParam.sequenceEngloberLine).getColor(); + final Color backColor = getHtmlColor(param, ColorParam.sequenceEngloberBackground).getColor(); + return new ComponentRoseEnglober(borderColor, backColor, stringsToDisplay, getFontColor(param, + FontParam.SEQUENCE_ENGLOBER), param.getFont(FontParam.SEQUENCE_ENGLOBER)); + } + return null; + } + + public Object getProtocolVersion() { + return 1; + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/StateDiagram.java b/src/net/sourceforge/plantuml/statediagram/StateDiagram.java new file mode 100644 index 000000000..a16feb1f3 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/StateDiagram.java @@ -0,0 +1,102 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5190 $ + * + */ +package net.sourceforge.plantuml.statediagram; + +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; + +public class StateDiagram extends AbstractEntityDiagram { + + @Override + public IEntity getOrCreateClass(String code) { + if (code.startsWith("[*]")) { + throw new IllegalArgumentException(); + } + if (isGroup(code)) { + return getGroup(code).getEntityCluster(); + } + final IEntity result = getOrCreateEntity(code, EntityType.STATE); + return result; + } + + public IEntity getStart() { + final Group g = getCurrentGroup(); + if (g == null) { + return getOrCreateEntity("*start", EntityType.CIRCLE_START); + } + return getOrCreateEntity("*start*" + g.getCode(), EntityType.CIRCLE_START); + } + + public IEntity getEnd() { + final Group p = getCurrentGroup(); + if (p == null) { + return getOrCreateEntity("*end", EntityType.CIRCLE_END); + } + return getOrCreateEntity("*end*" + p.getCode(), EntityType.CIRCLE_END); + } + + public boolean concurrentState() { + final Group cur = getCurrentGroup(); + if (cur != null && cur.getType() == GroupType.CONCURRENT_STATE) { + super.endGroup(); + } + final Group conc1 = getOrCreateGroup("CONC" + UniqueSequence.getValue(), "", null, GroupType.CONCURRENT_STATE, + getCurrentGroup()); + conc1.setDashed(true); + if (cur != null && cur.getType() == GroupType.STATE) { + cur.moveEntitiesTo(conc1); + super.endGroup(); + final Group conc2 = getOrCreateGroup("CONC" + UniqueSequence.getValue(), "", null, + GroupType.CONCURRENT_STATE, getCurrentGroup()); + conc2.setDashed(true); + } + return true; + } + + @Override + public void endGroup() { + super.endGroup(); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.STATE; + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java b/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java new file mode 100644 index 000000000..4d24a0e67 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5493 $ + * + */ +package net.sourceforge.plantuml.statediagram; + +import net.sourceforge.plantuml.classdiagram.command.CommandMultilinesClassNote; +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.command.CommandNoteEntity; +import net.sourceforge.plantuml.statediagram.command.CommandAddField; +import net.sourceforge.plantuml.statediagram.command.CommandConcurrentState; +import net.sourceforge.plantuml.statediagram.command.CommandCreatePackageState; +import net.sourceforge.plantuml.statediagram.command.CommandCreatePackageState2; +import net.sourceforge.plantuml.statediagram.command.CommandCreateState; +import net.sourceforge.plantuml.statediagram.command.CommandCreateState2; +import net.sourceforge.plantuml.statediagram.command.CommandEndState; +import net.sourceforge.plantuml.statediagram.command.CommandLinkState2; +import net.sourceforge.plantuml.usecasediagram.command.CommandRankDirUsecase; + +public class StateDiagramFactory extends AbstractUmlSystemCommandFactory { + + private StateDiagram system; + + public StateDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new StateDiagram(); + + addCommand(new CommandRankDirUsecase(system)); + addCommand(new CommandCreateState(system)); + addCommand(new CommandCreateState2(system)); + //addCommand(new CommandLinkState(system)); + addCommand(new CommandLinkState2(system)); + addCommand(new CommandCreatePackageState(system)); + addCommand(new CommandCreatePackageState2(system)); + addCommand(new CommandEndState(system)); + addCommand(new CommandAddField(system)); + addCommand(new CommandConcurrentState(system)); + addCommand(new CommandMultilinesClassNote(system)); + + addCommand(new CommandNoteEntity(system)); + addCommonCommands(system); + } +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java b/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java new file mode 100644 index 000000000..04dfb9c65 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandAddField extends SingleLineCommand { + + public CommandAddField(StateDiagram diagram) { + super(diagram, "(?i)^([\\p{L}0-9_.]+)\\s*:\\s*(.*)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Entity entity = (Entity) getSystem().getOrCreateClass(arg.get(0)); + + entity.addField(arg.get(1)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandConcurrentState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandConcurrentState.java new file mode 100644 index 000000000..6e57396c4 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandConcurrentState.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandConcurrentState extends SingleLineCommand { + + public CommandConcurrentState(StateDiagram classDiagram) { + super(classDiagram, "(?i)^--+$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().concurrentState()) { + return CommandExecutionResult.ok(); + } + return CommandExecutionResult.error("Error 42"); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java new file mode 100644 index 000000000..dd665ee9c --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandCreatePackageState extends SingleLineCommand { + + public CommandCreatePackageState(StateDiagram diagram) { + super(diagram, "(?i)^state\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)(?:\\s*\\{|\\s+begin)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + String display = arg.get(0); + final String code = arg.get(1); + if (display == null) { + display = code; + } + final Group p = getSystem().getOrCreateGroup(code, display, null, GroupType.STATE, currentPackage); + p.setRounded(true); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java new file mode 100644 index 000000000..1a2d2aaa4 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java @@ -0,0 +1,60 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandCreatePackageState2 extends SingleLineCommand { + + public CommandCreatePackageState2(StateDiagram diagram) { + super(diagram, "(?i)^state\\s+([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"(?:\\s*\\{|\\s+begin)$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + final String code = arg.get(0); + final String display = arg.get(1); + final Group p = getSystem().getOrCreateGroup(code, display, null, GroupType.STATE, currentPackage); + p.setRounded(true); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java new file mode 100644 index 000000000..f91de7ab9 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java @@ -0,0 +1,66 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandCreateState extends SingleLineCommand { + + public CommandCreateState(StateDiagram diagram) { + super(diagram, "(?i)^(?:state\\s+)(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)$"); + } + + /* + * @Override protected boolean isForbidden(String line) { if + * (line.matches("^[\\p{L}0-9_.]+$")) { return true; } return false; } + */ + + @Override + protected CommandExecutionResult executeArg(List arg) { + String display = arg.get(0); + final String code = arg.get(1); + if (display == null) { + display = code; + } + final Entity ent = (Entity) getSystem().getOrCreateClass(code); + ent.setDisplay(display); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java new file mode 100644 index 000000000..4bca92502 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5019 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandCreateState2 extends SingleLineCommand { + + public CommandCreateState2(StateDiagram diagram) { + super(diagram, "(?i)^(?:state\\s+)([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String code = arg.get(0); + final String display = arg.get(1); + final Entity ent = (Entity) getSystem().getOrCreateClass(code); + ent.setDisplay(display); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandEndState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandEndState.java new file mode 100644 index 000000000..0fa9e0553 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandEndState.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandEndState extends SingleLineCommand { + + public CommandEndState(StateDiagram diagram) { + super(diagram, "(?i)^(end ?state|\\})$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final Group currentPackage = getSystem().getCurrentGroup(); + if (currentPackage == null) { + return CommandExecutionResult.error("No inner state defined"); + } + getSystem().endGroup(); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java new file mode 100644 index 000000000..7518450ee --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java @@ -0,0 +1,88 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5441 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandLinkState extends SingleLineCommand { + + public CommandLinkState(StateDiagram diagram) { + super(diagram, "(?i)^([\\p{L}0-9_.]+|\\[\\*\\])\\s*" + "(-+(?:left|right|up|down|le?|ri?|up?|do?)?-*[\\]>])" + + "\\s*([\\p{L}0-9_.]+|\\[\\*\\])\\s*(?::\\s*([^\"]+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final IEntity cl1 = getEntityStart(arg.get(0)); + final IEntity cl2 = getEntityEnd(arg.get(2)); + + final String queueRaw = arg.get(1).substring(0, arg.get(1).length() - 1); + final Direction direction = StringUtils.getQueueDirection(queueRaw); + final String queue = StringUtils.manageQueueForCuca(queueRaw); + final int lenght = queue.length(); + + Link link = new Link(cl1, cl2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), arg.get(3), lenght); + getSystem().addLink(link); + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + + return CommandExecutionResult.ok(); + } + + private IEntity getEntityStart(String code) { + if (code.startsWith("[*]")) { + return getSystem().getStart(); + } + return getSystem().getOrCreateClass(code); + } + + private IEntity getEntityEnd(String code) { + if (code.startsWith("[*]")) { + return getSystem().getEnd(); + } + return getSystem().getOrCreateClass(code); + } + +} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java new file mode 100644 index 000000000..3273a68e2 --- /dev/null +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java @@ -0,0 +1,118 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5441 $ + * + */ +package net.sourceforge.plantuml.statediagram.command; + +import java.util.Map; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.statediagram.StateDiagram; + +public class CommandLinkState2 extends SingleLineCommand2 { + + public CommandLinkState2(StateDiagram diagram) { + super(diagram, getRegex()); + // "(?i)^([\\p{L}0-9_.]+|\\[\\*\\])\\s*" + + // "(-+(?:left|right|up|down|le?|ri?|up?|do?)?-*[\\]>])" + // + "\\s*([\\p{L}0-9_.]+|\\[\\*\\])\\s*(?::\\s*([^\"]+))?$"); + } + + static RegexConcat getRegex() { + return new RegexConcat(new RegexLeaf("^"), getStatePattern("ENT1"), new RegexLeaf("\\s*"), new RegexLeaf( + "ARROW", "((-+)(left|right|up|down|le?|ri?|up?|do?)?(-*)([\\]>]))"), new RegexLeaf("\\s*"), + getStatePattern("ENT2"), new RegexLeaf("\\s*"), new RegexLeaf("LABEL", "(?::\\s*([^\"]+))?"), + new RegexLeaf("$")); + } + + private static RegexLeaf getStatePattern(String name) { + return new RegexLeaf(name, "([\\p{L}0-9_.]+|\\[\\*\\])"); + } + + @Override + protected CommandExecutionResult executeArg(Map arg) { + final String ent1 = arg.get("ENT1").get(0); + final String ent2 = arg.get("ENT2").get(0); + + final IEntity cl1 = getEntityStart(ent1); + final IEntity cl2 = getEntityEnd(ent2); + + String queue = arg.get("ARROW").get(1) + arg.get("ARROW").get(3); + final Direction dir = getDirection(arg); + + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + queue = "-"; + } + + final int lenght = queue.length(); + + Link link = new Link(cl1, cl2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), arg.get("LABEL").get(0), lenght); + if (dir == Direction.LEFT || dir == Direction.UP) { + link = link.getInv(); + } + getSystem().addLink(link); + + return CommandExecutionResult.ok(); + } + + private Direction getDirection(Map arg) { + if (arg.get("ARROW").get(2) != null) { + return StringUtils.getQueueDirection(arg.get("ARROW").get(2)); + } + return null; + } + + private IEntity getEntityStart(String code) { + if (code.startsWith("[*]")) { + return getSystem().getStart(); + } + return getSystem().getOrCreateClass(code); + } + + private IEntity getEntityEnd(String code) { + if (code.startsWith("[*]")) { + return getSystem().getEnd(); + } + return getSystem().getOrCreateClass(code); + } + +} diff --git a/src/net/sourceforge/plantuml/sudoku/DLXEngine.java b/src/net/sourceforge/plantuml/sudoku/DLXEngine.java new file mode 100644 index 000000000..2055c114f --- /dev/null +++ b/src/net/sourceforge/plantuml/sudoku/DLXEngine.java @@ -0,0 +1,1175 @@ +/**************************************************************************** + * DLXEngine.java + * + * Created on den 30 december 2005, 01:04 + * + * DLXEngine + * Sudoku puzzle generator and solver based on the suexg and suexk by + * Gunter Stertenbrink. Suexg and suexk are C implementations of the + * Dancing Links algorithm by Donald Knuth and optimized for performance + * which means that certain cleanup work has been done. There is still + * lots of these activities left to do, however, the code is nasty and + * hard to read - but extremely efficient. + * + * The code is public domain so feel free to use it. + *****************************************************************************/ + +package net.sourceforge.plantuml.sudoku; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Random; + +/******************************************************************************* + * dlx_solver solve any Sudoku in a fraction of a second. Input is a string of + * dots and digits representing the puzzle to solve and output is the solved + * puzzle. + * + * @author Rolf Sandberg + ******************************************************************************/ +class dlx_solver { + static final int M = 8; // change this for larger grids. Use symbols as in + // L[] below + static final int M2 = M * M; + static final int M4 = M2 * M2; + + /** Pseudo-random number generator */ + long MWC() { + return random.nextLong(); + } + + int A0[][] = new int[M2 + 9][M2 + 9], A[][] = new int[M2 + 9][M2 + 9], Rows[] = new int[4 * M4 + 9], + Cols[] = new int[M2 * M4 + 9], Row[][] = new int[4 * M4 + 9][M2 + 9]; + int Col[][] = new int[M2 * M4 + 9][5], Ur[] = new int[M2 * M4 + 9], Uc[] = new int[4 * M4 + 9], V[] = new int[M2 + * M4 + 9]; + int C[] = new int[M4 + 9], I[] = new int[M4 + 9], T[] = new int[M2 * M4 + 9], P[] = new int[M2 * M4 + 9]; + int Mr[] = { 0, 1, 63, 1023, 4095, 16383, 46655, 131071, 262143 }; + int Mc[] = { 0, 1, 63, 511, 1023, 4095, 8191, 16383, 16383 }; + int Mw[] = { 0, 1, 3, 15, 15, 31, 63, 63, 63 }; + + int nocheck = 0, max, _try_; + final int rnd = 0; + int min, clues, gu, tries; + long Node[] = new long[M4 + 9]; + long nodes, tnodes, solutions, vmax, smax, time0, time1, t1, x1; + double xx, yy; + int q, a, p, i, i1, j, k, l, r, r1, c, c1, c2, n, N = 0, N2, N4, m, m0, m1, x, y, s; + char L[] = { '.', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '#', '*', '~' }; + + /** State machine states */ + static final int M6 = 10; + static final int M7 = 11; + static final int RESTART = 12; + static final int M22 = 13; + static final int M3 = 14; + static final int M44 = 15; + static final int NEXT_TRY = 16; + static final int END = 30; + + /** + * Solver function. Input parameter: A puzzle to solve Output: The solved + * puzzle + */ + String solve(String puzzle) { + String result = new String(); + int STATE = M6; + + vmax = 4000000; + smax = 25; + p = 1; + q = 0; + + if (q > 0) { + vmax = 99999999; + smax = 99999999; + } + + N = 3; + N2 = N * N; + N4 = N2 * N2; + m = 4 * N4; + n = N2 * N4; + + if (puzzle.length() < N4) { + return "Error, puzzle incomplete"; + } + + while (STATE != END) { + switch (STATE) { + case M6: + clues = 0; + i = 0; + for (x = 0; x < N2; x++) + for (y = 0; y < N2; y++) { + c = puzzle.charAt(x * N2 + y); + j = 0; + + if (c == '-' || c == '.' || c == '0' || c == '*') { + A0[x][y] = j; + i++; + } else { + while (L[j] != c && j <= N2) + j++; + + if (j <= N2) { + A0[x][y] = j; + if (j > 0) + clues++; + i++; + } + } + } + + if (clues == N4) { + clues--; + A0[1][1] = 0; + } + + if (p < 8) { + for (i = 0; i <= N4; i++) + Node[i] = 0; + } + tnodes = 0; + + case RESTART: + r = 0; + for (x = 1; x <= N2; x++) + for (y = 1; y <= N2; y++) + for (s = 1; s <= N2; s++) { + r++; + Cols[r] = 4; + Col[r][1] = x * N2 - N2 + y; + Col[r][4] = (N * ((x - 1) / N) + (y - 1) / N) * N2 + s + N4; + + Col[r][3] = x * N2 - N2 + s + N4 * 2; + Col[r][2] = y * N2 - N2 + s + N4 * 3; + } + for (c = 1; c <= m; c++) + Rows[c] = 0; + + for (r = 1; r <= n; r++) + for (c = 1; c <= Cols[r]; c++) { + x = Col[r][c]; + Rows[x]++; + Row[x][Rows[x]] = r; + } + + for (x = 0; x < N2; x++) + for (y = 0; y < N2; y++) + A[x][y] = A0[x][y]; + + for (i = 0; i <= n; i++) + Ur[i] = 0; + for (i = 0; i <= m; i++) + Uc[i] = 0; + + solutions = 0; + + for (x = 1; x <= N2; x++) + for (y = 1; y <= N2; y++) + if (A[x - 1][y - 1] > 0) { + r = x * N4 - N4 + y * N2 - N2 + A[x - 1][y - 1]; + + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + if (Uc[c1] > 0 && nocheck == 0) { + STATE = NEXT_TRY; + break; + } + + Uc[c1]++; + + for (k = 1; k <= Rows[c1]; k++) { + r1 = Row[c1][k]; + Ur[r1]++; + } + } + if (STATE == NEXT_TRY) + break; + } + if (STATE == NEXT_TRY) + break; + + if (rnd > 0 && rnd != 17 && rnd != 18) + shuffle(); + + for (c = 1; c <= m; c++) { + V[c] = 0; + for (r = 1; r <= Rows[c]; r++) + if (Ur[Row[c][r]] == 0) + V[c]++; + } + + i = clues; + nodes = 0; + m0 = 0; + m1 = 0; + gu = 0; + solutions = 0; + + case M22: + i++; + I[i] = 0; + min = n + 1; + if (i > N4 || m0 > 0) { + STATE = M44; + break; + } + if (m1 > 0) { + C[i] = m1; + STATE = M3; + break; + } + for (c = 1; c <= m; c++) + if (Uc[c] == 0) { + if (V[c] <= min) + c1 = c; + if (V[c] < min) { + min = V[c]; + C[i] = c; + if (min < 2) { + STATE = M3; + break; + } + } + } + if (STATE == M3) + break; + + gu++; + if (min > 2) { + STATE = M3; + break; + } + + if ((rnd & 255) == 18) + if ((nodes & 1) > 0) { + c = m + 1; + c--; + while (Uc[c] > 0 || V[c] != 2) + c--; + C[i] = c; + } + + if ((rnd & 255) == 17) { + c1 = (int) (MWC() & Mc[N]); + while (c1 >= m) + c1 = (int) (MWC() & Mc[N]); + c1++; + + for (c = c1; c <= m; c++) + if (Uc[c] == 0) + if (V[c] == 2) { + C[i] = c; + STATE = M3; + break; + } + for (c = 1; c < c1; c++) + if (Uc[c] == 0) + if (V[c] == 2) { + C[i] = c; + STATE = M3; + break; + } + } + + case M3: + c = C[i]; + I[i]++; + if (I[i] > Rows[c]) { + STATE = M44; + break; + } + + r = Row[c][I[i]]; + if (Ur[r] > 0) { + STATE = M3; + break; + } + m0 = 0; + m1 = 0; + + if (q > 0 && i > 32 && i < 65) + if ((MWC() & 127) < q) { + STATE = M3; + break; + } + + k = N4; + x = (r - 1) / k + 1; + y = ((r - 1) % k) / j + 1; + s = (r - 1) % j + 1; + + if ((p & 1) > 0) { + j = N2; + k = N4; + x = (r - 1) / k + 1; + y = ((r - 1) % k) / j + 1; + s = (r - 1) % j + 1; + A[x - 1][y - 1] = s; + if (i == k) { + for (x = 0; x < j; x++) + for (y = 0; y < j; y++) + result = result.concat(String.valueOf(L[A[x][y]])); + result = result.concat(" #\n"); + } + } + + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + Uc[c1]++; + } + + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + + for (k = 1; k <= Rows[c1]; k++) { + r1 = Row[c1][k]; + Ur[r1]++; + if (Ur[r1] == 1) + for (l = 1; l <= Cols[r1]; l++) { + c2 = Col[r1][l]; + V[c2]--; + + if (Uc[c2] + V[c2] < 1) + m0 = c2; + if (Uc[c2] == 0 && V[c2] < 2) + m1 = c2; + } + } + } + Node[i]++; + tnodes++; + nodes++; + if (rnd > 99 && nodes > rnd) { + STATE = RESTART; + break; + } + if (i == N4) + solutions++; + + if (solutions >= smax) { + System.out.println("smax xolutions found"); + if (_try_ == 1) + System.out.print("+"); + STATE = NEXT_TRY; + break; + } + if (tnodes > vmax) { + if (_try_ == 1) + System.out.print("-"); + STATE = NEXT_TRY; + break; + } + STATE = M22; + break; + + case M44: + i--; + c = C[i]; + r = Row[c][I[i]]; + if (i == clues) { + STATE = NEXT_TRY; + break; + } + + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + Uc[c1]--; + + for (k = 1; k <= Rows[c1]; k++) { + r1 = Row[c1][k]; + Ur[r1]--; + + if (Ur[r1] == 0) + for (l = 1; l <= Cols[r1]; l++) { + c2 = Col[r1][l]; + V[c2]++; + } + } + } + if (p > 0) { + j = N2; + k = N4; + x = (r - 1) / k + 1; + y = ((r - 1) % k) / j + 1; + s = (r - 1) % j + 1; + A[x - 1][y - 1] = 0; + } + if (i > clues) { + STATE = M3; + break; + } + + case NEXT_TRY: + time1 = System.currentTimeMillis(); + x1 = time1 - time0; + + time0 = time1; + + if (q > 0) { + xx = 128; + yy = 128 - q; + xx = xx / yy; + yy = solutions; + for (i = 1; i < 33; i++) + yy = yy * xx; + System.out.println("clues: " + clues + " estimated solutions:" + yy + " time " + x1 + "ms"); + + STATE = END; + break; + } + if ((p == 0 || p == 1) && tnodes <= 999999) { + if (solutions >= smax) + result = result.concat("More than " + solutions + " solutions ( bad sudoku!! ), rating " + + (100 * tnodes / solutions) + ", time " + x1 + " ms"); + else if (solutions == 1) + result = result.concat(solutions + " solution, rating " + (100 * tnodes) + ", time " + x1 + + " ms"); + else if (solutions == 0) + result = result.concat("0 solutions, no rating possible, time " + x1 + " ms"); + else + result = result.concat(solutions + " solutions ( bad sudoku!! ), rating " + + (100 * tnodes / solutions) + ", time " + x1 + " ms"); + + STATE = END; + break; + } + if (p == 6) { + System.out.println(solutions); + STATE = END; + break; + } + if (p == 0 || p == 1) { + System.out.println(solutions + " solution(s), rating " + (100 * tnodes) + ", time " + x1 + "ms"); + } + if (p > 5) { + x = 0; + for (i = 1; i <= N4; i++) { + x += Node[i]; + System.out.print(Node[i]); + if (i % 9 == 0) + System.out.println(); + } + System.out.println(x); + } + STATE = END; + break; + } // end of switch statement + } // end of while loop + return result; + } + + /** + * Helper function. + */ + int shuffle() { + for (i = 1; i <= m; i++) { + a = (int) ((MWC() >> 8) & Mc[N]); + while (a >= i) + a = (int) ((MWC() >> 8) & Mc[N]); + a++; + P[i] = P[a]; + P[a] = i; + } + + for (c = 1; c <= m; c++) { + Rows[c] = 0; + T[c] = Uc[c]; + } + + for (c = 1; c <= m; c++) + Uc[P[c]] = T[c]; + + for (r = 1; r <= n; r++) + for (i = 1; i <= Cols[r]; i++) { + c = P[Col[r][i]]; + Col[r][i] = c; + Rows[c]++; + Row[c][Rows[c]] = r; + } + + for (i = 1; i <= n; i++) { + a = (int) ((MWC() >> 8) & Mr[N]); + while (a >= i) + a = (int) ((MWC() >> 8) & Mr[N]); + a++; + P[i] = P[a]; + P[a] = i; + } + + for (r = 1; r <= n; r++) { + Cols[r] = 0; + T[r] = Ur[r]; + } + + for (r = 1; r <= n; r++) + Ur[P[r]] = T[r]; + + for (c = 1; c <= m; c++) + for (i = 1; i <= Rows[c]; i++) { + r = P[Row[c][i]]; + Row[c][i] = r; + Cols[r]++; + Col[r][Cols[r]] = c; + } + + for (r = 1; r <= n; r++) { + for (i = 1; i <= Cols[r]; i++) { + a = (int) ((MWC() >> 8) & 7); + while (a >= i) + a = (int) ((MWC() >> 8) & 7); + a++; + P[i] = P[a]; + P[a] = i; + } + + for (i = 1; i <= Cols[r]; i++) + T[i] = Col[r][P[i]]; + + for (i = 1; i <= Cols[r]; i++) + Col[r][i] = T[i]; + } + + for (c = 1; c <= m; c++) { + for (i = 1; i <= Rows[c]; i++) { + a = (int) ((MWC() >> 8) & Mw[N]); + while (a >= i) + a = (int) ((MWC() >> 8) & Mw[N]); + a++; + P[i] = P[a]; + P[a] = i; + } + + for (i = 1; i <= Rows[c]; i++) + T[i] = Row[c][P[i]]; + + for (i = 1; i <= Rows[c]; i++) + Row[c][i] = T[i]; + } + return 0; + } + + private final Random random; + + /** Creates a new instance of dlx_solver */ + public dlx_solver(Random random) { + this.random = random; + } +} + +/******************************************************************************* + * dlx_generator generate single solution locally minimized Sudoku puzzles. + * Locally minimized means that all keys that can be removed without creating a + * degenerate Sudoku (multiple solutions) are removed. + ******************************************************************************/ +class dlx_generator { + long MWC() { + return random.nextLong(); + } + + int Rows[] = new int[325], Cols[] = new int[730], Row[][] = new int[325][10], Col[][] = new int[730][5], + Ur[] = new int[730], Uc[] = new int[325], V[] = new int[325], W[] = new int[325]; + int P[] = new int[88], A[] = new int[88], C[] = new int[88], I[] = new int[88], Two[] = new int[888]; + char B[] = { '0', '1', '1', '1', '2', '2', '2', '3', '3', '3', '1', '1', '1', '2', '2', '2', '3', '3', '3', '1', + '1', '1', '2', '2', '2', '3', '3', '3', '4', '4', '4', '5', '5', '5', '6', '6', '6', '4', '4', '4', '5', + '5', '5', '6', '6', '6', '4', '4', '4', '5', '5', '5', '6', '6', '6', '7', '7', '7', '8', '8', '8', '9', + '9', '9', '7', '7', '7', '8', '8', '8', '9', '9', '9', '7', '7', '7', '8', '8', '8', '9', '9', '9' }; + char H[][] = new char[326][7]; + long c2, w; + int b, f, s1, m0, c1, r1, l, i1, m1, m2, a, p, i, j, k, r, c, d, n = 729, m = 324, x, y, s, z, fi; + int mi1, mi2, q7, part, nt, rate, nodes, solutions, min, samples, sam1, clues; + char L[] = { '.', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + + /** State machine states */ + static final int M0S = 10; + static final int M0 = 11; + static final int MR1 = 12; + static final int MR3 = 13; + static final int MR4 = 14; + static final int M2 = 15; + static final int M3 = 16; + static final int M4 = 17; + static final int M9 = 18; + static final int MR = 19; + static final int END = 20; + static final int M6 = 21; + + /** Set to true to generate debug output */ + boolean DBG = false; + + /** Output trace messages */ + void dbg(String s) { + if (DBG) + System.out.println(s); + } + + private final Random random; + + public dlx_generator(Random random) { + dbg("In constructor"); + this.random = random; + } + + /** + * Save the generated Sudoku to a file. + */ + void saveSudokuToFile(String s) { + FileOutputStream FO = null; + byte[] buffer = new byte[s.length() + 1]; + int i = 0; + + while (i < s.length()) { + buffer[i] = (byte) s.charAt(i); + i++; + } + + try { + FO = new FileOutputStream("generated_sudoku.sdk"); + FO.write(buffer); + FO.close(); + } catch (IOException IOE) { + // Well, well, well.... + return; + } + } + + /** + * Initialization code for both generate() and rate() + */ + void initialize() { + for (i = 0; i < 888; i++) { + j = 1; + while (j <= i) + j += j; + Two[i] = j - 1; + } + + r = 0; + for (x = 1; x <= 9; x++) + for (y = 1; y <= 9; y++) + for (s = 1; s <= 9; s++) { + r++; + Cols[r] = 4; + Col[r][1] = x * 9 - 9 + y; + Col[r][2] = (B[x * 9 - 9 + y] - 48) * 9 - 9 + s + 81; + Col[r][3] = x * 9 - 9 + s + 81 * 2; + Col[r][4] = y * 9 - 9 + s + 81 * 3; + } + + for (c = 1; c <= m; c++) + Rows[c] = 0; + + for (r = 1; r <= n; r++) + for (c = 1; c <= Cols[r]; c++) { + a = Col[r][c]; + Rows[a]++; + Row[a][Rows[a]] = r; + } + + c = 0; + for (x = 1; x <= 9; x++) + for (y = 1; y <= 9; y++) { + c++; + H[c][0] = 'r'; + H[c][1] = L[x]; + H[c][2] = 'c'; + H[c][3] = L[y]; + H[c][4] = 0; + } + + c = 81; + for (b = 1; b <= 9; b++) + for (s = 1; s <= 9; s++) { + c++; + H[c][0] = 'b'; + H[c][1] = L[b]; + H[c][2] = 's'; + H[c][3] = L[s]; + H[c][4] = 0; + } + + c = 81 * 2; + for (x = 1; x <= 9; x++) + for (s = 1; s <= 9; s++) { + c++; + H[c][0] = 'r'; + H[c][1] = L[x]; + H[c][2] = 's'; + H[c][3] = L[s]; + H[c][4] = 0; + } + + c = 81 * 3; + for (y = 1; y <= 9; y++) + for (s = 1; s <= 9; s++) { + c++; + H[c][0] = 'c'; + H[c][1] = L[y]; + H[c][2] = 's'; + H[c][3] = L[s]; + H[c][4] = 0; + } + } + + /* + * Rating function + */ + public long rate(String puzzle) { + int STATE = M6; + int Solutions; + + z = 100; + fi = 0; + rate = 1; + + for (i = 0; i < 88; i++) + A[i] = 0; + + initialize(); + + while (STATE != END) { + switch (STATE) { + case M6: + clues = 0; + for (i = 1; i <= 81; i++) { + c = puzzle.charAt(i - 1); + j = 0; + + if (c == '-' || c == '.' || c == '0' || c == '*') { + A[i] = j; + } else { + while (L[j] != c && j <= 9) + j++; + + if (j <= 9) { + A[i] = j; + } + } + } + + if (clues == 81) { + clues--; + A[1] = 0; + } + + nt = 0; + mi1 = 9999; + for (f = 0; f < z; f++) { + Solutions = solve(); + if (Solutions != 1) { + if (Solutions > 1) + nt = -1 * Solutions; + STATE = END; + break; + } + nt += nodes; + if (nodes < mi1) { + mi1 = nodes; + mi2 = C[clues]; + } + } + if (STATE == END) + break; + + if (fi > 0) + if ((nt / z) > fi) { + for (i = 1; i <= 81; i++) + System.out.println(L[A[i]]); + System.out.println(); + STATE = M6; + break; + } + + if (fi > 0) { + STATE = M6; + break; + } + + if ((z & 1) > 0) { + System.out.println(nt / z); + STATE = M6; + break; + } + + if (rate > 1) + System.out.println("hint: " + H[mi2]); + + STATE = END; + break; + } // End of switch statement + } // End of while loop + return (nt); + } + + public String[] generate(int Samples, int Rate) { + int STATE = M0S; + String result[] = new String[Samples]; + + dbg("Entering generate"); + + samples = 1000; + if (Samples > 0) + samples = Samples; + + for (i = 0; i < samples; i++) + result[i] = new String(); + + // Set to 1 for rating, set to 2 for rating and hint + rate = 0; + if (Rate > 0) + rate = Rate; + if (rate > 2) + rate = 2; + + initialize(); + + dbg("Entering state machine"); + + sam1 = -1; + while (STATE != END) { + switch (STATE) { + case M0S: + sam1++; + if (sam1 >= samples) { + STATE = END; + break; + } + + case M0: + for (i = 1; i <= 81; i++) + A[i] = 0; + part = 0; + q7 = 0; + + case MR1: + i1 = (int) ((MWC() >> 8) & 127); + if (i1 > 80) { + STATE = MR1; + break; + } + + i1++; + if (A[i1] > 0) { + STATE = MR1; + break; + } + + case MR3: + s = (int) ((MWC() >> 9) & 15); + if (s > 8) { + STATE = MR3; + break; + } + + s++; + A[i1] = s; + m2 = solve(); + q7++; + + if (m2 < 1) + A[i1] = 0; + + if (m2 != 1) { + STATE = MR1; + break; + } + + part++; + if (solve() != 1) { + STATE = M0; + break; + } + + case MR4: + for (i = 1; i <= 81; i++) { + x = (int) ((MWC() >> 8) & 127); + while (x >= i) { + x = (int) ((MWC() >> 8) & 127); + } + x++; + P[i] = P[x]; + P[x] = i; + } + + for (i1 = 1; i1 <= 81; i1++) { + s1 = A[P[i1]]; + A[P[i1]] = 0; + if (solve() > 1) + A[P[i1]] = s1; + } + + if (rate > 0) { + nt = 0; + mi1 = 9999; + for (f = 0; f < 100; f++) { + solve(); + nt += nodes; + if (nodes < mi1) { + mi1 = nodes; + mi2 = C[clues]; + } + } + result[sam1] = result[sam1].concat("Rating:" + nt + "# "); + if (rate > 1) { + result[sam1] = result[sam1].concat("hint: " + String.valueOf(H[mi2]).substring(0, 4) + " #\n"); + } else + result[sam1] = result[sam1].concat("\n"); + } + + for (i = 1; i <= 81; i++) { + result[sam1] = result[sam1].concat(String.valueOf(L[A[i]])); + if (i % 9 == 0) { + result[sam1] = result[sam1].concat("\n"); + } + } + result[sam1] = result[sam1].concat("\n"); + + default: + dbg("Default case. New state M0S"); + STATE = M0S; + break; + } // end of switch statement + } // end of while loop + return result; + } + + int solve() {// returns 0 (no solution), 1 (unique sol.), 2 (more than + // one sol.) + int STATE = M2; + + for (i = 0; i <= n; i++) + Ur[i] = 0; + for (i = 0; i <= m; i++) + Uc[i] = 0; + clues = 0; + + for (i = 1; i <= 81; i++) + if (A[i] > 0) { + clues++; + r = i * 9 - 9 + A[i]; + + for (j = 1; j <= Cols[r]; j++) { + d = Col[r][j]; + if (Uc[d] > 0) + return 0; + Uc[d]++; + + for (k = 1; k <= Rows[d]; k++) { + Ur[Row[d][k]]++; + } + } + } + + for (c = 1; c <= m; c++) { + V[c] = 0; + for (r = 1; r <= Rows[c]; r++) + if (Ur[Row[c][r]] == 0) + V[c]++; + } + + i = clues; + m0 = 0; + m1 = 0; + solutions = 0; + nodes = 0; + + dbg("Solve: Entering state machine"); + + while (STATE != END) { + switch (STATE) { + case M2: + i++; + I[i] = 0; + min = n + 1; + if ((i > 81) || (m0 > 0)) { + STATE = M4; + break; + } + + if (m1 > 0) { + C[i] = m1; + STATE = M3; + break; + } + + w = 0; + for (c = 1; c <= m; c++) + if (Uc[c] == 0) { + if (V[c] < 2) { + C[i] = c; + STATE = M3; + break; + } + + if (V[c] <= min) { + w++; + W[(int) w] = c; + } + ; + + if (V[c] < min) { + w = 1; + W[(int) w] = c; + min = V[c]; + } + } + + if (STATE == M3) { + // break in for loop detected, continue breaking + break; + } + + case MR: + c2 = (MWC() & Two[(int) w]); + while (c2 >= w) { + c2 = (MWC() & Two[(int) w]); + } + C[i] = W[(int) c2 + 1]; + + case M3: + c = C[i]; + I[i]++; + if (I[i] > Rows[c]) { + STATE = M4; + break; + } + + r = Row[c][I[i]]; + if (Ur[r] > 0) { + STATE = M3; + break; + } + m0 = 0; + m1 = 0; + nodes++; + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + Uc[c1]++; + } + + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + for (k = 1; k <= Rows[c1]; k++) { + r1 = Row[c1][k]; + Ur[r1]++; + if (Ur[r1] == 1) + for (l = 1; l <= Cols[r1]; l++) { + c2 = Col[r1][l]; + V[(int) c2]--; + if (Uc[(int) c2] + V[(int) c2] < 1) + m0 = (int) c2; + if (Uc[(int) c2] == 0 && V[(int) c2] < 2) + m1 = (int) c2; + } + } + } + + if (i == 81) + solutions++; + + if (solutions > 1) { + STATE = M9; + break; + } + STATE = M2; + break; + + case M4: + i--; + if (i == clues) { + STATE = M9; + break; + } + c = C[i]; + r = Row[c][I[i]]; + + for (j = 1; j <= Cols[r]; j++) { + c1 = Col[r][j]; + Uc[c1]--; + for (k = 1; k <= Rows[c1]; k++) { + r1 = Row[c1][k]; + Ur[r1]--; + if (Ur[r1] == 0) + for (l = 1; l <= Cols[r1]; l++) { + c2 = Col[r1][l]; + V[(int) c2]++; + } + } + } + + if (i > clues) { + STATE = M3; + break; + } + + case M9: + STATE = END; + break; + default: + STATE = END; + break; + } // end of switch statement + } // end of while statement + return solutions; + } +} + +/** + * + * @author Rolf Sandberg + */ + +public class DLXEngine { + dlx_generator generator; + dlx_solver solver; + + public DLXEngine(Random random) { + generator = new dlx_generator(random); + solver = new dlx_solver(random); + } + + String generate(int minrating, int maxrating) { + // Date t = new Date(); + // long start = t.getTime(); + // int tries = 0, i, samples = 5; + // long rating = 0; + String ss[] = generator.generate(1, 0); + return ss[0]; + + // Generator: + // First arg: rand seed + // Second arg: #samples, ignored if <= 0 + // Third arg: rating and hints, ignored if <= 0 + + // Task: Find a Sudoku with a rating in a specified interval. + // Do it by generating samples and examine them + // Continue until an appropriate puzzle is found. + // while(tries < 9999999) { + // tries++; + // t = new Date(); + // ss = generator.generate(samples, 0); + // for(i = 0; i < samples; i++) { + // rating = generator.rate(ss[i].replace("\n","").trim()); + // if(rating > minrating && rating < maxrating) { + // return ss[i]; + // } + // } + // System.out.println(minrating + ", " + maxrating + ", " + rating + ", + // looping"); + // } + // return ss[0]; + } + + long rate(String s) { + return generator.rate(s); + } + + String solve(String s) { + String result = solver.solve(s); + return result; + } +} diff --git a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java new file mode 100644 index 000000000..3eafb07ce --- /dev/null +++ b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java @@ -0,0 +1,123 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4125 $ + * + */ +package net.sourceforge.plantuml.sudoku; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.png.PngIO; + +public class GraphicsSudoku { + + private final ISudoku sudoku; + private final Font numberFont = new Font("SansSerif", Font.BOLD, 20); + private final Font font = new Font("SansSerif", Font.PLAIN, 11); + + public GraphicsSudoku(ISudoku sudoku) { + this.sudoku = sudoku; + } + + public void writeImage(OutputStream os) throws IOException { + final BufferedImage im = createImage(); + PngIO.write(im, os); + } + + final private int xOffset = 5; + final private int yOffset = 5; + + final private int cellWidth = 30; + final private int cellHeight = 32; + + final private int numberxOffset = 10; + final private int numberyOffset = 5; + + final private int textTotalHeight = 50; + + private BufferedImage createImage() { + final int boldWidth = 3; + final int sudoHeight = 9 * cellHeight + 2 * yOffset + boldWidth; + final int sudoWidth = 9 * cellWidth + 2 * xOffset + boldWidth; + + final EmptyImageBuilder builder = new EmptyImageBuilder(sudoWidth, sudoHeight + textTotalHeight, Color.WHITE); + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + g2d.translate(xOffset, yOffset); + + for (int x = 0; x < 9; x++) { + for (int y = 0; y < 9; y++) { + final int num = sudoku.getGiven(x, y); + if (num > 0) { + final TextBlock text = TextBlockUtils.create(Arrays.asList("" + num), numberFont, Color.BLACK, + HorizontalAlignement.CENTER); + text.drawTOBEREMOVED(g2d, numberxOffset + x * cellWidth, numberyOffset + y * cellHeight); + } + } + } + + for (int i = 0; i < 10; i++) { + final boolean bold = i % boldWidth == 0; + final int w = bold ? boldWidth : 1; + g2d.fillRect(0, i * cellHeight, 9 * cellWidth + boldWidth, w); + } + for (int i = 0; i < 10; i++) { + final boolean bold = i % boldWidth == 0; + final int w = bold ? boldWidth : 1; + g2d.fillRect(i * cellWidth, 0, w, 9 * cellHeight + boldWidth); + } + + g2d.translate(0, sudoHeight); + final List texts = new ArrayList(); + texts.add("http://plantuml.sourceforge.net"); + texts.add("Seed " + Long.toString(sudoku.getSeed(), 36)); + texts.add("Difficulty " + sudoku.getRatting()); + final TextBlock textBlock = TextBlockUtils.create(texts, font, Color.BLACK, HorizontalAlignement.LEFT); + textBlock.drawTOBEREMOVED(g2d, 0, 0); + + g2d.dispose(); + return im; + } + +} diff --git a/src/net/sourceforge/plantuml/sudoku/ISudoku.java b/src/net/sourceforge/plantuml/sudoku/ISudoku.java new file mode 100644 index 000000000..f5e6af2cc --- /dev/null +++ b/src/net/sourceforge/plantuml/sudoku/ISudoku.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.sudoku; + +public interface ISudoku { + + int getGiven(int x, int y); + + long getRatting(); + + long getSeed(); + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java b/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java new file mode 100644 index 000000000..28692037e --- /dev/null +++ b/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4041 $ + * + */ +package net.sourceforge.plantuml.sudoku; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.List; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; + +public class PSystemSudoku extends AbstractPSystem { + + final private ISudoku sudoku; + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + new GraphicsSudoku(sudoku).writeImage(os); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + new GraphicsSudoku(sudoku).writeImage(os); + } + + public String getDescription() { + return "(Sudoku)"; + } + + public PSystemSudoku(Long seed) { + sudoku = new SudokuDLX(seed); + } + +} diff --git a/src/net/sourceforge/plantuml/sudoku/PSystemSudokuFactory.java b/src/net/sourceforge/plantuml/sudoku/PSystemSudokuFactory.java new file mode 100644 index 000000000..e9c55368c --- /dev/null +++ b/src/net/sourceforge/plantuml/sudoku/PSystemSudokuFactory.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.sudoku; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemSudokuFactory implements PSystemBasicFactory { + + private PSystemSudoku system; + + public PSystemSudokuFactory() { + reset(); + } + + public void reset() { + } + + public PSystemSudoku getSystem() { + return system; + } + + final private static Pattern p = Pattern.compile("(?i)^sudoku(?:\\s+([0-9a-zA-Z]+))?\\s*$"); + + public boolean executeLine(String line) { + final Matcher m = p.matcher(line); + if (m.find() == false) { + return false; + } + + if (m.group(1) == null) { + system = new PSystemSudoku(null); + } else { + system = new PSystemSudoku(Long.parseLong(m.group(1).toLowerCase(), 36)); + } + return true; + + } +} diff --git a/src/net/sourceforge/plantuml/sudoku/SudokuDLX.java b/src/net/sourceforge/plantuml/sudoku/SudokuDLX.java new file mode 100644 index 000000000..cba67231d --- /dev/null +++ b/src/net/sourceforge/plantuml/sudoku/SudokuDLX.java @@ -0,0 +1,87 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.sudoku; + +import java.util.Random; + +public class SudokuDLX implements ISudoku { + + private final String tab[]; + private final long seed; + private final long rate; + + public SudokuDLX(Long seed) { + if (seed == null) { + this.seed = Math.abs(new Random().nextLong()); + } else { + this.seed = Math.abs(seed.longValue()); + } + final DLXEngine engine = new DLXEngine(new Random(this.seed)); + final String s = engine.generate(10000, 100000); + rate = engine.rate(s.replace("\n", "").trim()); + tab = s.split("\\s"); + } + + public long getRatting() { + return rate; + } + + public long getSeed() { + return seed; + } + + public int getGiven(int x, int y) { + final char c = tab[x].charAt(y); + if (c == '.') { + return 0; + } + return c - '0'; + } + + public void print() { + for (String s : tab) { + System.err.println(s); + } + System.err.println("Rate=" + rate); + System.err.println("Seed=" + Long.toString(seed, 36).toUpperCase()); + } + + public static void main(String[] args) { + for (int i = 0; i < 1; i++) { + final SudokuDLX sudoku = new SudokuDLX(null); + sudoku.print(); + } + } + +} diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java new file mode 100644 index 000000000..b502e5814 --- /dev/null +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -0,0 +1,385 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5361 $ + * + */ +package net.sourceforge.plantuml.svg; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.ugraphic.UPath; +import net.sourceforge.plantuml.ugraphic.USegmentType; +import net.sourceforge.plantuml.ugraphic.USegment; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class SvgGraphics { + + // http://tutorials.jenkov.com/svg/index.html + // http://www.svgbasics.com/ + // http://apike.ca/prog_svg_text.html + // http://www.w3.org/TR/SVG11/shapes.html + // http://en.wikipedia.org/wiki/Scalable_Vector_Graphics + + final private Document document; + final private Element svg; + final private Element defs; + final private Element g; + + private String fill = "black"; + private String stroke = "black"; + private String strokeWidth = "1"; + private String strokeDasharray = null; + + public SvgGraphics() { + this(null); + } + + public SvgGraphics(String backcolor) { + try { + document = getDocument(); + + svg = getRootNode("100%", "100%", "absolute", "0", "0", backcolor); + + // Create a node named defs, which will be the parent + // for a pair of linear gradient definitions. + defs = simpleElement("defs"); + g = simpleElement("g"); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + throw new IllegalStateException(e); + } + + } + + // This method returns a reference to a simple XML + // element node that has no attributes. + private Element simpleElement(String type) { + final Element theElement = (Element) document.createElement(type); + svg.appendChild(theElement); + return theElement; + } + + private Document getDocument() throws ParserConfigurationException { + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + final DocumentBuilder builder = factory.newDocumentBuilder(); + final Document document = builder.newDocument(); + document.setXmlStandalone(true); + return document; + } + + // This method returns a reference to a root node that + // has already been appended to the document. + private Element getRootNode(String width, String height, String position, String top, String left, String backcolor) { + // Create the root node named svg and append it to + // the document. + final Element svg = (Element) document.createElement("svg"); + document.appendChild(svg); + + // Set some attributes on the root node that are + // required for proper rendering. Note that the + // approach used here is somewhat different from the + // approach used in the earlier program named Svg01, + // particularly with regard to the style. + svg.setAttribute("xmlns", "http://www.w3.org/2000/svg"); + svg.setAttribute("version", "1.1"); + String style = "width:" + width + ";height:" + height + ";position:" + position + ";top:" + top + ";left:" + + left + ";"; + if (backcolor != null) { + style += "background:" + backcolor + ";"; + } + svg.setAttribute("style", style); + + return svg; + } + + + public void svgEllipse(double x, double y, double xRadius, double yRadius) { + final Element elt = (Element) document.createElement("ellipse"); + elt.setAttribute("cx", "" + x); + elt.setAttribute("cy", "" + y); + elt.setAttribute("rx", "" + xRadius); + elt.setAttribute("ry", "" + yRadius); + elt.setAttribute("fill", fill); + elt.setAttribute("style", getStyle()); + getG().appendChild(elt); + } + + private Map, String> gradients = new HashMap, String>(); + + public String createSvgGradient(String color1, String color2) { + final List key = Arrays.asList(color1, color2); + String id = gradients.get(key); + if (id == null) { + final Element elt = (Element) document.createElement("linearGradient"); + elt.setAttribute("x1", "0%"); + elt.setAttribute("y1", "0%"); + elt.setAttribute("x2", "100%"); + elt.setAttribute("y2", "100%"); + id = "gr" + gradients.size(); + gradients.put(key, id); + elt.setAttribute("id", id); + + final Element stop1 = (Element) document.createElement("stop"); + stop1.setAttribute("stop-color", color1); + stop1.setAttribute("offset", "0%"); + final Element stop2 = (Element) document.createElement("stop"); + stop2.setAttribute("stop-color", color2); + stop2.setAttribute("offset", "100%"); + + elt.appendChild(stop1); + elt.appendChild(stop2); + defs.appendChild(elt); + } + return id; + } + + public final void setFillColor(String fill) { + this.fill = fill == null ? "none" : fill; + } + + public final void setStrokeColor(String stroke) { + this.stroke = stroke; + } + + public final void setStrokeWidth(String strokeWidth, String strokeDasharray) { + this.strokeWidth = strokeWidth; + this.strokeDasharray = strokeDasharray; + } + + public void svgRectangle(double x, double y, double width, double height, double rx, double ry) { + final Element elt = (Element) document.createElement("rect"); + elt.setAttribute("x", "" + x); + elt.setAttribute("y", "" + y); + elt.setAttribute("width", "" + width); + elt.setAttribute("height", "" + height); + elt.setAttribute("fill", fill); + elt.setAttribute("style", getStyle()); + if (rx > 0 && ry > 0) { + elt.setAttribute("rx", "" + rx); + elt.setAttribute("ry", "" + ry); + } + getG().appendChild(elt); + } + + public void svgLine(double x1, double y1, double x2, double y2) { + final Element elt = (Element) document.createElement("line"); + elt.setAttribute("x1", "" + x1); + elt.setAttribute("y1", "" + y1); + elt.setAttribute("x2", "" + x2); + elt.setAttribute("y2", "" + y2); + elt.setAttribute("style", getStyle()); + getG().appendChild(elt); + } + + private String getStyle() { + final StringBuilder style = new StringBuilder("stroke: " + stroke + "; stroke-width: " + strokeWidth + ";"); + if (strokeDasharray != null) { + style.append(" stroke-dasharray: " + strokeDasharray + ";"); + } + return style.toString(); + } + + public void svgPolygon(double... points) { + final Element elt = (Element) document.createElement("polygon"); + final StringBuilder sb = new StringBuilder(); + for (double coord : points) { + if (sb.length() > 0) { + sb.append(","); + } + sb.append(coord); + } + elt.setAttribute("points", sb.toString()); + elt.setAttribute("fill", fill); + elt.setAttribute("style", getStyle()); + getG().appendChild(elt); + } + + public void text(String text, double x, double y, String fontFamily, int fontSize, String fontWeight, + String fontStyle, String textDecoration, double textLength) { + final Element elt = (Element) document.createElement("text"); + elt.setAttribute("x", "" + x); + elt.setAttribute("y", "" + y); + elt.setAttribute("fill", fill); + elt.setAttribute("font-size", "" + fontSize); + // elt.setAttribute("text-anchor", "middle"); + elt.setAttribute("lengthAdjust", "spacingAndGlyphs"); + elt.setAttribute("textLength", "" + textLength); + if (fontWeight != null) { + elt.setAttribute("font-weight", fontWeight); + } + if (fontStyle != null) { + elt.setAttribute("font-style", fontStyle); + } + if (textDecoration != null) { + elt.setAttribute("text-decoration", textDecoration); + } + elt.setTextContent(text); + getG().appendChild(elt); + } + + public final Element getDefs() { + return defs; + } + + public final Element getG() { + return g; + } + + private Transformer getTransformer() throws TransformerException { + // Get a TransformerFactory object. + final TransformerFactory xformFactory = TransformerFactory.newInstance(); + + // Get an XSL Transformer object. + final Transformer transformer = xformFactory.newTransformer(); + + // // Sets the standalone property in the first line of + // // the output file. + transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); + // + // Properties proprietes = new Properties(); + // proprietes.put("standalone", "yes"); + // transformer.setOutputProperties(proprietes); + // + // transformer.setParameter(OutputKeys.STANDALONE, "yes"); + + return transformer; + } + + public void createXml(OutputStream os) throws TransformerException { + + // Get a DOMSource object that represents the + // Document object + final DOMSource source = new DOMSource(document); + + // Get a StreamResult object that points to the + // screen. Then transform the DOM sending XML to + // the screen. + final StreamResult scrResult = new StreamResult(os); + getTransformer().transform(source, scrResult); + } + + public String getGElement() throws TransformerException, IOException { + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + final StreamResult sr = new StreamResult(os); + getTransformer().transform(new DOMSource(g), sr); + os.close(); + final String s = new String(os.toByteArray(), "UTF-8"); + return s.replaceFirst("^\\<\\?xml.*?\\?\\>", ""); + } + + public void svgPath(double x, double y, UPath path) { + final StringBuilder sb = new StringBuilder(); + for (USegment seg : path) { + final USegmentType type = seg.getSegmentType(); + final double coord[] = seg.getCoord(); + if (type == USegmentType.SEG_MOVETO) { + sb.append("M" + (coord[0] + x) + "," + (coord[1] + y) + " "); + } else if (type == USegmentType.SEG_LINETO) { + sb.append("L" + (coord[0] + x) + "," + (coord[1] + y) + " "); + } else if (type == USegmentType.SEG_QUADTO) { + sb.append("Q" + (coord[0] + x) + "," + (coord[1] + y) + " " + (coord[2] + x) + "," + (coord[3] + y) + + " "); + } else if (type == USegmentType.SEG_CLOSE) { + // Nothing + } else { + System.err.println("unknown " + seg); + } + + } + final Element elt = (Element) document.createElement("path"); + elt.setAttribute("d", sb.toString()); + elt.setAttribute("style", getStyle()); + getG().appendChild(elt); + } + + private StringBuilder currentPath = null; + + public void newpath() { + currentPath = new StringBuilder(); + + } + + public void moveto(double x, double y) { + currentPath.append("M" + format(x) + "," + format(y) + " "); + } + + public void lineto(double x, double y) { + currentPath.append("L" + format(x) + "," + format(y) + " "); + } + + public void closepath() { + currentPath.append("Z "); + + } + + public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) { + currentPath.append("C" + format(x1) + "," + format(y1) + " " + format(x2) + "," + format(y2) + " " + format(x3) + "," + format(y3) + " "); + + } + + public void quadto(double x1, double y1, double x2, double y2) { + currentPath.append("Q" + format(x1) + "," + format(y1) + " " + format(x2) + "," + format(y2) + " "); + } + + private static String format(double x) { + return EpsGraphics.format(x); + } + + public void fill(int windingRule) { + final Element elt = (Element) document.createElement("path"); + elt.setAttribute("d", currentPath.toString()); + //elt elt.setAttribute("style", getStyle()); + getG().appendChild(elt); + currentPath = null; + + } + +} diff --git a/src/net/sourceforge/plantuml/svg/SvgTitler.java b/src/net/sourceforge/plantuml/svg/SvgTitler.java new file mode 100644 index 000000000..0ef78a7c9 --- /dev/null +++ b/src/net/sourceforge/plantuml/svg/SvgTitler.java @@ -0,0 +1,141 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4173 $ + * + */ +package net.sourceforge.plantuml.svg; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Dimension2D; +import java.io.IOException; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMaker; +import net.sourceforge.plantuml.graphic.HorizontalAlignement; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.graphic.VerticalPosition; +import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; + +public final class SvgTitler { + + private final Color textColor; + private final List text; + // private final int fontSize; + // private final String fontFamily; + private final HorizontalAlignement horizontalAlignement; + private final VerticalPosition verticalPosition; + private final int margin; + private final TextBlock textBloc; + + public SvgTitler(Color textColor, List text, int fontSize, String fontFamily, + HorizontalAlignement horizontalAlignement, VerticalPosition verticalPosition, int margin) { + this.textColor = textColor; + this.text = text; + // this.fontSize = fontSize; + // this.fontFamily = fontFamily; + this.horizontalAlignement = horizontalAlignement; + this.verticalPosition = verticalPosition; + this.margin = margin; + if (text == null || text.size() == 0) { + textBloc = null; + } else { + final Font normalFont = new Font(fontFamily, Font.PLAIN, fontSize); + textBloc = TextBlockUtils.create(text, normalFont, textColor, HorizontalAlignement.LEFT); + } + } + + public double getHeight() { + if (textBloc == null) { + return 0; + } + return textBloc.calculateDimension(new UGraphicSvg(false).getStringBounder()).getHeight() + margin; + } + + public String addTitleSvg(String svg, double width, double height) throws IOException { + if (text == null || text.size() == 0) { + return svg; + } + + final UGraphicSvg uGraphicSvg = new UGraphicSvg(false); + final Dimension2D dimText = textBloc.calculateDimension(uGraphicSvg.getStringBounder()); + final double xpos; + + if (horizontalAlignement == HorizontalAlignement.LEFT) { + xpos = 2; + } else if (horizontalAlignement == HorizontalAlignement.RIGHT) { + xpos = width - dimText.getWidth() - 2; + } else if (horizontalAlignement == HorizontalAlignement.CENTER) { + xpos = (width - dimText.getWidth()) / 2; + } else { + xpos = 0; + assert false; + } + + final double yText; + + if (verticalPosition == VerticalPosition.TOP) { + yText = 0; + } else { + yText = height + margin; + } + + textBloc.drawU(uGraphicSvg, xpos, yText); + String svgTitle = CucaDiagramFileMaker.getSvg(uGraphicSvg); + svgTitle = svgTitle.replaceFirst("(?i)", ""); + + if (verticalPosition == VerticalPosition.TOP) { + final Pattern p = Pattern.compile("(?i)translate\\((\\d+)\\s+(\\d+)"); + final Matcher m = p.matcher(svg); + + final StringBuffer sb = new StringBuffer(); + while (m.find()) { + final int tx = Integer.parseInt(m.group(1)); + final int ty = Integer.parseInt(m.group(2)) + (int) (dimText.getHeight()) + margin; + m.appendReplacement(sb, "translate(" + tx + " " + ty); + } + m.appendTail(sb); + svg = sb.toString(); + } + + final int x = svg.indexOf(" currentDirectoryListing = new ArrayList(); + final private Set openWindows = new HashSet(); + final private Option option; + + private DirWatcher dirWatcher; + + public MainWindow(Option option) { + this(new File(prefs.get(KEY_DIR, ".")), option); + + } + + private String getExtensions() { + return prefs.get(KEY_PATTERN, getDefaultFileExtensions()); + } + + private String getDefaultFileExtensions() { + return "txt, tex, java, htm, html, c, h, cpp, apt"; + } + + private void changeExtensions(String ext) { + if (ext.equals(getExtensions())) { + return; + } + final Pattern p = Pattern.compile("\\w+"); + final Matcher m = p.matcher(ext); + final StringBuilder sb = new StringBuilder(); + + while (m.find()) { + final String value = m.group(); + if (sb.length() > 0) { + sb.append(", "); + } + sb.append(value); + + } + ext = sb.toString(); + if (ext.length() == 0) { + ext = getDefaultFileExtensions(); + } + extensions.setText(ext); + prefs.put(KEY_PATTERN, ext); + changeDir(dirWatcher.getDir()); + } + + private String getRegexpPattern(String ext) { + final Pattern p = Pattern.compile("\\w+"); + final Matcher m = p.matcher(ext); + final StringBuilder filePattern = new StringBuilder("(?i)^.*\\.("); + + while (m.find()) { + final String value = m.group(); + if (filePattern.toString().endsWith("(") == false) { + filePattern.append("|"); + } + filePattern.append(value); + } + if (filePattern.toString().endsWith("(") == false) { + filePattern.append(")$"); + return filePattern.toString(); + } + return Option.getPattern(); + } + + private MainWindow(File dir, Option option) { + super(dir.getAbsolutePath()); + this.option = option; + dirWatcher = new DirWatcher(dir, option, getRegexpPattern(getExtensions())); + + Log.info("Showing MainWindow"); + scrollPane = new JScrollPane(jList1); + + final JPanel south = new JPanel(new BorderLayout()); + final JLabel labelFileExtensions = new JLabel("File extensions: "); + extensions.setText(getExtensions()); + + labelFileExtensions.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6)); + south.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3), BorderFactory + .createEtchedBorder())); + south.add(labelFileExtensions, BorderLayout.WEST); + south.add(extensions, BorderLayout.CENTER); + + south.add(changeDirButton, BorderLayout.SOUTH); + + getContentPane().add(south, BorderLayout.SOUTH); + getContentPane().add(scrollPane, BorderLayout.CENTER); + setSize(320, 200); + setVisible(true); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + final MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + final int index = jList1.locationToIndex(e.getPoint()); + doubleClick((SimpleLine) jList1.getModel().getElementAt(index)); + } + } + }; + jList1.addMouseListener(mouseListener); + changeDirButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.err.println("Opening Directory Window"); + displayDialogChangeDir(); + } + }); + + extensions.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + changeExtensions(extensions.getText()); + } + }); + extensions.addFocusListener(new FocusListener() { + + public void focusGained(FocusEvent e) { + } + + public void focusLost(FocusEvent e) { + changeExtensions(extensions.getText()); + } + }); + + startTimer(); + } + + private void startTimer() { + Log.info("Init done"); + final Timer timer = new Timer(3000, new ActionListener() { + public void actionPerformed(ActionEvent e) { + tick(); + } + }); + timer.setInitialDelay(0); + timer.start(); + Log.info("Timer started"); + } + + private void displayDialogChangeDir() { + final JFileChooser chooser = new JFileChooser(); + chooser.setDialogType(JFileChooser.CUSTOM_DIALOG); + chooser.setDialogTitle("Directory to watch:"); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + final String currentPath = prefs.get(KEY_DIR, "."); + chooser.setCurrentDirectory(new File(currentPath)); + Log.info("Showing OpenDialog"); + final int returnVal = chooser.showOpenDialog(this); + Log.info("Closing OpenDialog"); + if (returnVal == JFileChooser.APPROVE_OPTION) { + final File dir = chooser.getSelectedFile(); + changeDir(dir); + } + + } + + private void changeDir(File dir) { + prefs.put(KEY_DIR, dir.getAbsolutePath()); + dirWatcher = new DirWatcher(dir, option, getRegexpPattern(getExtensions())); + setTitle(dir.getAbsolutePath()); + Log.info("Creating DirWatcher"); + currentDirectoryListing.clear(); + jList1.setListData(new Vector(currentDirectoryListing)); + jList1.setVisible(true); + } + + private void doubleClick(SimpleLine simpleLine) { + for (ImageWindow win : openWindows) { + if (win.getSimpleLine().equals(simpleLine)) { + win.setVisible(true); + win.setExtendedState(Frame.NORMAL); + return; + } + } + openWindows.add(new ImageWindow(simpleLine, this)); + } + + private void tick() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + final boolean changed = refreshDir(); + if (changed) { + jList1.setListData(new Vector(currentDirectoryListing)); + jList1.setVisible(true); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }); + } + + private boolean refreshDir() throws IOException, InterruptedException { + final Collection createdFiles2 = dirWatcher.buildCreatedFiles(); + + boolean changed = false; + + for (GeneratedImage g : createdFiles2) { + final SimpleLine simpleLine = new SimpleLine(g); + mayRefreshImageWindow(g.getPngFile()); + if (currentDirectoryListing.contains(simpleLine) == false) { + removeAllThatUseThisFile(g.getPngFile()); + currentDirectoryListing.add(simpleLine); + changed = true; + } + } + for (final Iterator it = currentDirectoryListing.iterator(); it.hasNext();) { + final SimpleLine s = it.next(); + if (s.exists() == false) { + it.remove(); + changed = true; + } + + } + Collections.sort(currentDirectoryListing); + return changed; + } + + private void removeAllThatUseThisFile(File pngFile) { + for (final Iterator it = currentDirectoryListing.iterator(); it.hasNext();) { + final SimpleLine line = it.next(); + if (line.getGeneratedImage().getPngFile().equals(pngFile)) { + it.remove(); + } + + } + + } + + private void mayRefreshImageWindow(File pngFile) { + for (ImageWindow win : openWindows) { + if (pngFile.equals(win.getSimpleLine().getGeneratedImage().getPngFile())) { + win.refreshImage(); + } + } + + } + + public void closing(ImageWindow imageWindow) { + final boolean ok = openWindows.remove(imageWindow); + if (ok == false) { + throw new IllegalStateException(); + } + } + +} diff --git a/src/net/sourceforge/plantuml/swing/ScrollablePicture.java b/src/net/sourceforge/plantuml/swing/ScrollablePicture.java new file mode 100644 index 000000000..4e91364b2 --- /dev/null +++ b/src/net/sourceforge/plantuml/swing/ScrollablePicture.java @@ -0,0 +1,129 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.swing; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; + +class ScrollablePicture extends JLabel implements Scrollable, MouseMotionListener { + + private int maxUnitIncrement = 1; + private boolean missingPicture = false; + + public ScrollablePicture(ImageIcon i, int m) { + super(i); + if (i == null) { + missingPicture = true; + setText("No picture found."); + setHorizontalAlignment(CENTER); + setOpaque(true); + setBackground(Color.white); + } + maxUnitIncrement = m; + + // Let the user scroll by dragging to outside the window. + setAutoscrolls(true); // enable synthetic drag events + addMouseMotionListener(this); // handle mouse drags + } + + // Methods required by the MouseMotionListener interface: + public void mouseMoved(MouseEvent e) { + } + + public void mouseDragged(MouseEvent e) { + // The user is dragging us, so scroll! + Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1); + scrollRectToVisible(r); + } + + @Override + public Dimension getPreferredSize() { + if (missingPicture) { + return new Dimension(320, 480); + } else { + return super.getPreferredSize(); + } + } + + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + // Get the current position. + int currentPosition = 0; + if (orientation == SwingConstants.HORIZONTAL) { + currentPosition = visibleRect.x; + } else { + currentPosition = visibleRect.y; + } + + // Return the number of pixels between currentPosition + // and the nearest tick mark in the indicated direction. + if (direction < 0) { + int newPosition = currentPosition - (currentPosition / maxUnitIncrement) * maxUnitIncrement; + return (newPosition == 0) ? maxUnitIncrement : newPosition; + } else { + return ((currentPosition / maxUnitIncrement) + 1) * maxUnitIncrement - currentPosition; + } + } + + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.HORIZONTAL) { + return visibleRect.width - maxUnitIncrement; + } else { + return visibleRect.height - maxUnitIncrement; + } + } + + public boolean getScrollableTracksViewportWidth() { + return false; + } + + public boolean getScrollableTracksViewportHeight() { + return false; + } + + public void setMaxUnitIncrement(int pixels) { + maxUnitIncrement = pixels; + } +} diff --git a/src/net/sourceforge/plantuml/swing/SimpleLine.java b/src/net/sourceforge/plantuml/swing/SimpleLine.java new file mode 100644 index 000000000..4085307e6 --- /dev/null +++ b/src/net/sourceforge/plantuml/swing/SimpleLine.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.swing; + +import net.sourceforge.plantuml.GeneratedImage; + +class SimpleLine implements Comparable { + + private final GeneratedImage generatedImage; + + public SimpleLine(GeneratedImage generatedImage) { + this.generatedImage = generatedImage; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(generatedImage.getPngFile().getName()); + sb.append(" "); + sb.append(generatedImage.getDescription()); + return sb.toString(); + } + + @Override + public int hashCode() { + return generatedImage.hashCode(); + } + + @Override + public boolean equals(Object obj) { + final SimpleLine this2 = (SimpleLine) obj; + return this2.generatedImage.equals(this.generatedImage); + } + + public boolean exists() { + return generatedImage.getPngFile().exists(); + } + + public int compareTo(SimpleLine this2) { + return this.generatedImage.compareTo(this2.generatedImage); + } + + public GeneratedImage getGeneratedImage() { + return generatedImage; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java b/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java new file mode 100644 index 000000000..ac13bd3bc --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +public abstract class AbstractCommonUGraphic implements UGraphic { + + private final UParam param = new UParam(); + private double dx; + private double dy; + + final public UParam getParam() { + return param; + } + + final public void translate(double dx, double dy) { + this.dx += dx; + this.dy += dy; + } + + final public void setTranslate(double dx, double dy) { + this.dx = dx; + this.dy = dy; + } + + final public double getTranslateX() { + return dx; + } + + final public double getTranslateY() { + return dy; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/AbstractUGraphic.java b/src/net/sourceforge/plantuml/ugraphic/AbstractUGraphic.java new file mode 100644 index 000000000..94e796c55 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/AbstractUGraphic.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4206 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.util.HashMap; +import java.util.Map; + +public abstract class AbstractUGraphic extends AbstractCommonUGraphic { + + private final O g2d; + + private final Map, UDriver> drivers = new HashMap, UDriver>(); + + public AbstractUGraphic(O g2d) { + this.g2d = g2d; + } + + protected final O getGraphicObject() { + return g2d; + } + + final protected void registerDriver(Class cl, UDriver driver) { + this.drivers.put(cl, driver); + } + + public final void draw(double x, double y, UShape shape) { + final UDriver driver = drivers.get(shape.getClass()); + if (driver == null) { + throw new UnsupportedOperationException(shape.getClass().toString() + " " + this.getClass()); + } + driver.draw(shape, x + getTranslateX(), y + getTranslateY(), getParam(), g2d); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/ClipContainer.java b/src/net/sourceforge/plantuml/ugraphic/ClipContainer.java new file mode 100644 index 000000000..6a40381e9 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/ClipContainer.java @@ -0,0 +1,36 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic; + +public interface ClipContainer { + public UClip getClip(); +} diff --git a/src/net/sourceforge/plantuml/ugraphic/ColorChanger.java b/src/net/sourceforge/plantuml/ugraphic/ColorChanger.java new file mode 100644 index 000000000..e8b503b68 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/ColorChanger.java @@ -0,0 +1,41 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4912 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Color; + +public interface ColorChanger { + + Color getChangedColor(Color color); +} diff --git a/src/net/sourceforge/plantuml/ugraphic/ColorChangerIdentity.java b/src/net/sourceforge/plantuml/ugraphic/ColorChangerIdentity.java new file mode 100644 index 000000000..e48ae2ab4 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/ColorChangerIdentity.java @@ -0,0 +1,43 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4912 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Color; + +public class ColorChangerIdentity implements ColorChanger { + + public Color getChangedColor(Color color) { + return color; + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/ColorChangerMonochrome.java b/src/net/sourceforge/plantuml/ugraphic/ColorChangerMonochrome.java new file mode 100644 index 000000000..002ec135b --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/ColorChangerMonochrome.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4912 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Color; + +public class ColorChangerMonochrome implements ColorChanger { + + public Color getChangedColor(Color color) { + if (color==null) { + return null; + } + final int grayScale = (int) (color.getRed() * .3 + color.getGreen() * .59 + color.getBlue() * .11); + return new Color(grayScale, grayScale, grayScale); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UClip.java b/src/net/sourceforge/plantuml/ugraphic/UClip.java new file mode 100644 index 000000000..75f3771f6 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UClip.java @@ -0,0 +1,94 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.geom.Rectangle2D; + +public class UClip { + + private final double x; + private final double y; + private final double width; + private final double height; + + public UClip(double x, double y, double width, double height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + @Override + public String toString() { + return "CLIP x=" + x + " y=" + y + " w=" + width + " h=" + height; + } + + public UClip translate(double dx, double dy) { + return new UClip(x + dx, y + dy, width, height); + } + + public final double getX() { + return x; + } + + public final double getY() { + return y; + } + + public final double getWidth() { + return width; + } + + public final double getHeight() { + return height; + } + + public boolean isInside(double xp, double yp) { + if (xp < x) { + return false; + } + if (xp > x + width) { + return false; + } + if (yp < y) { + return false; + } + if (yp > y + height) { + return false; + } + return true; + } + + public Rectangle2D.Double getClippedRectangle(Rectangle2D.Double r) { + return (Rectangle2D.Double) r.createIntersection(new Rectangle2D.Double(x, y, width, height)); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UDriver.java b/src/net/sourceforge/plantuml/ugraphic/UDriver.java new file mode 100644 index 000000000..4a5e949cf --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UDriver.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +public interface UDriver { + public void draw(UShape shape, double x, double y, UParam param, O object); + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UEllipse.java b/src/net/sourceforge/plantuml/ugraphic/UEllipse.java new file mode 100644 index 000000000..2303af747 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UEllipse.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4901 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +public class UEllipse implements UShape { + + private final double width; + private final double height; + private final double start; + private final double extend; + + public UEllipse(double width, double height) { + this(width, height, 0, 0); + } + + public UEllipse(double width, double height, double start, double extend) { + this.width = width; + this.height = height; + this.start = start; + this.extend = extend; + } + + public double getWidth() { + return width; + } + + public double getHeight() { + return height; + } + + public final double getStart() { + return start; + } + + public final double getExtend() { + return extend; + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UGradient.java b/src/net/sourceforge/plantuml/ugraphic/UGradient.java new file mode 100644 index 000000000..de7230b07 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UGradient.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Color; + +public class UGradient { + + private final Color color1; + private final Color color2; + + public UGradient(Color color1, Color color2) { + if (color1 == null || color2 == null) { + throw new IllegalArgumentException(); + } + this.color1 = color1; + this.color2 = color2; + + } + + public final Color getColor1() { + return color1; + } + + public final Color getColor2() { + return color2; + } + + public final Color getColor(double coeff) { + if (coeff > 1 || coeff < 0) { + throw new IllegalArgumentException("c=" + coeff); + } + final int vred = color2.getRed() - color1.getRed(); + final int vgreen = color2.getGreen() - color1.getGreen(); + final int vblue = color2.getBlue() - color1.getBlue(); + + final int red = color1.getRed() + (int) (coeff * vred); + final int green = color1.getGreen() + (int) (coeff * vgreen); + final int blue = color1.getBlue() + (int) (coeff * vblue); + + return new Color(red, green, blue); + + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphic.java b/src/net/sourceforge/plantuml/ugraphic/UGraphic.java new file mode 100644 index 000000000..300677158 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphic.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4129 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Font; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public interface UGraphic { + + public StringBounder getStringBounder(); + + public UParam getParam(); + + public void draw(double x, double y, UShape shape); + public void centerChar(double x, double y, char c, Font font); + + public void translate(double dx, double dy); + public void setTranslate(double dx, double dy); + + public double getTranslateX(); + + public double getTranslateY(); + + public void setClip(UClip clip); + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java b/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java new file mode 100644 index 000000000..69375e0f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4129 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Font; + +import net.sourceforge.plantuml.graphic.StringBounder; + +public abstract class UGraphicUtils { + + public static UGraphic translate(final UGraphic g, final double tx, final double ty) { + return new UGraphic() { + + public void centerChar(double x, double y, char c, Font font) { + g.centerChar(tx + x, ty + y, c, font); + } + + public void draw(double x, double y, UShape shape) { + g.draw(tx + x, ty + y, shape); + } + + public UParam getParam() { + return g.getParam(); + } + + public StringBounder getStringBounder() { + return g.getStringBounder(); + } + + public double getTranslateX() { + return g.getTranslateX(); + } + + public double getTranslateY() { + return g.getTranslateY(); + } + + public void setClip(UClip clip) { + throw new UnsupportedOperationException(); + } + + public void setTranslate(double dx, double dy) { + g.setTranslate(dx, dy); + } + + public void translate(double dx, double dy) { + g.translate(dx, dy); + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UImage.java b/src/net/sourceforge/plantuml/ugraphic/UImage.java new file mode 100644 index 000000000..479115ed2 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UImage.java @@ -0,0 +1,50 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3961 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.image.BufferedImage; + +public class UImage implements UShape { + + private final BufferedImage image; + + public UImage(BufferedImage image) { + this.image = image; + } + + public final BufferedImage getImage() { + return image; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/ULine.java b/src/net/sourceforge/plantuml/ugraphic/ULine.java new file mode 100644 index 000000000..e13fd2e80 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/ULine.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4681 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +public class ULine implements UShape { + + private final double dx; + private final double dy; + + public ULine(double dx, double dy) { + this.dx = dx; + this.dy = dy; + } + + @Override + public String toString() { + return "ULine dx=" + dx + " dy=" + dy; + } + + public double getDX() { + return dx; + } + + public double getDY() { + return dy; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UMotif.java b/src/net/sourceforge/plantuml/ugraphic/UMotif.java new file mode 100644 index 000000000..165b896a9 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UMotif.java @@ -0,0 +1,171 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4206 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.posimo.DotPath; + +public class UMotif { + + private final List points = new ArrayList(); + + public UMotif(int... data) { + for (int i = 0; i < data.length; i += 2) { + points.add(new Point2D.Double(data[i], data[i + 1])); + } + } + + public UMotif(String s) { + final Point2D last = new Point2D.Double(); + for (int i = 0; i < s.length(); i++) { + final Point2D read = convertPoint(s.charAt(i)); + last.setLocation(last.getX() + read.getX(), last.getY() + + read.getY()); + points.add(new Point2D.Double(last.getX(), last.getY())); + } + } + + double getLength() { + return points.get(0).distance(points.get(points.size()-1)); + } + + List getPoints() { + return Collections.unmodifiableList(points); + } + + public DotPath getRectangle(double width, double height) { + final double len = getLength(); + final int nb1 = (int)(width / len); + DotPath h1 = drawHorizontal(0, 0, nb1); + final int nb2 = (int)(height / len); + final DotPath v1 = drawVertical(h1.getEndPoint().getX(), h1.getEndPoint().getY(), nb2); + h1 = h1.addAfter(v1); + return h1; + } + + static Point2D convertPoint(char c) { + final int v = convertFromChar(c); + final int x = v % 7; + final int y = v / 7; + return new Point2D.Double(x - 3, y - 3); + } + + static int convertFromChar(char c) { + if (c >= 'A' && c <= 'Z') { + return c - 'A'; + } + if (c >= 'a' && c <= 'w') { + return c - 'a' + 26; + } + throw new IllegalArgumentException(); + } + + // public void drawOld(UGraphic ug, double x, double y) { + // final UPath path = new UPath(); + // path.add(new double[] { x, y }, USegmentType.SEG_MOVETO); + // for (Point2D p : points) { + // path.add(new double[] { x + p.getX(), y + p.getY() }, + // USegmentType.SEG_LINETO); + // } + // ug.draw(0, 0, path); + // } + + public void drawHorizontal(UGraphic ug, double x, double y, int nb) { + final DotPath path = drawHorizontal(x, y, nb); + ug.draw(0, 0, path); + } + + public void drawVertical(UGraphic ug, double x, double y, int nb) { + final DotPath path = drawVertical(x, y, nb); + ug.draw(0, 0, path); + } + + DotPath drawHorizontal(double x, double y, int nb) { + DotPath path = new DotPath(); + for (int i = 0; i < nb; i++) { + path = addHorizontal(x, y, path); + x = path.getEndPoint().getX(); + y = path.getEndPoint().getY(); + } + return path; + } + + DotPath drawVertical(double x, double y, int nb) { + DotPath path = new DotPath(); + for (int i = 0; i < nb; i++) { + path = addVertical(x, y, path); + x = path.getEndPoint().getX(); + y = path.getEndPoint().getY(); + } + return path; + } + + private DotPath addHorizontal(double x, double y, DotPath path) { + double lastx = 0; + double lasty = 0; + for (Point2D p : points) { + final double x1 = lastx + x; + final double y1 = lasty + y; + final double x2 = p.getX() + x; + final double y2 = p.getY() + y; + path = path.addAfter(new CubicCurve2D.Double(x1, y1, x1, y1, x2, + y2, x2, y2)); + lastx = p.getX(); + lasty = p.getY(); + } + return path; + } + + private DotPath addVertical(double x, double y, DotPath path) { + double lastx = 0; + double lasty = 0; + for (Point2D p : points) { + final double x1 = lastx + x; + final double y1 = lasty + y; + final double x2 = p.getY() + x; + final double y2 = p.getX() + y; + path = path.addAfter(new CubicCurve2D.Double(x1, y1, x1, y1, x2, + y2, x2, y2)); + lastx = p.getY(); + lasty = p.getX(); + } + return path; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UParam.java b/src/net/sourceforge/plantuml/ugraphic/UParam.java new file mode 100644 index 000000000..3f92c3983 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UParam.java @@ -0,0 +1,93 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4918 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.Color; + +public class UParam { + + private Color color = null; + private Color backcolor = null; + private UStroke stroke = new UStroke(1); + private UGradient gradient = null; + private ColorChanger colorChanger = new ColorChangerIdentity(); + + public void reset() { + color = null; + backcolor = null; + gradient = null; + stroke = new UStroke(1); + colorChanger = new ColorChangerIdentity(); + } + + public final UGradient getGradient() { + return gradient; + } + + public final void setGradient(UGradient gradient) { + this.gradient = gradient; + } + + public void setColor(Color color) { + this.color = color; + } + + public Color getColor() { + return colorChanger.getChangedColor(color); + } + + public void setBackcolor(Color color) { + this.backcolor = color; + } + + public Color getBackcolor() { + return colorChanger.getChangedColor(backcolor); + } + + public void setStroke(UStroke stroke) { + this.stroke = stroke; + } + + public UStroke getStroke() { + return stroke; + } + + private void setColorChanger(ColorChanger colorChanger) { + if (colorChanger == null) { + throw new IllegalArgumentException(); + } + this.colorChanger = colorChanger; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UPath.java b/src/net/sourceforge/plantuml/ugraphic/UPath.java new file mode 100644 index 000000000..0107b573d --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UPath.java @@ -0,0 +1,57 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class UPath implements UShape, Iterable { + + private final List segments = new ArrayList(); + + public void add(double[] coord, USegmentType pathType) { + segments.add(new USegment(coord, pathType)); + } + + @Override + public String toString() { + return segments.toString(); + } + + public Iterator iterator() { + return segments.iterator(); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UPolygon.java b/src/net/sourceforge/plantuml/ugraphic/UPolygon.java new file mode 100644 index 000000000..6cafee9fd --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UPolygon.java @@ -0,0 +1,59 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5392 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +public class UPolygon implements UShape { + + private final List all = new ArrayList(); + + public void addPoint(double x, double y) { + all.add(new Point2D.Double(x, y)); + } + + public List getPoints() { + return all; + } + + public void rotate(double theta) { + final AffineTransform rotate = AffineTransform.getRotateInstance(theta); + for (Point2D.Double pt : all) { + rotate.transform(pt, pt); + } + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/URectangle.java b/src/net/sourceforge/plantuml/ugraphic/URectangle.java new file mode 100644 index 000000000..3ba19549b --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/URectangle.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic; + +public class URectangle implements UShape { + + private final double width; + private final double height; + private final double rx; + private final double ry; + + public URectangle(double width, double height) { + this(width, height, 0, 0); + } + + public URectangle(double width, double height, double rx, double ry) { +// if (height == 0) { +// throw new IllegalArgumentException(); +// } + if (width == 0) { + throw new IllegalArgumentException(); + } + this.width = width; + this.height = height; + this.rx = rx; + this.ry = ry; + } + + @Override + public String toString() { + return "width=" + width + " height=" + height; + } + + public double getWidth() { + return width; + } + + public double getHeight() { + return height; + } + + public double getRx() { + return rx; + } + + public double getRy() { + return ry; + } + + public URectangle clip(UClip clip) { + return this; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/USegment.java b/src/net/sourceforge/plantuml/ugraphic/USegment.java new file mode 100644 index 000000000..3430144cd --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/USegment.java @@ -0,0 +1,61 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.util.Arrays; + +public class USegment { + + private final double coord[]; + private final USegmentType pathType; + + public USegment(double[] coord, USegmentType pathType) { + this.coord = coord.clone(); + this.pathType = pathType; + } + + @Override + public String toString() { + return pathType.toString() + " " + Arrays.toString(coord); + } + + public final double[] getCoord() { + return coord; + } + + public final USegmentType getSegmentType() { + return pathType; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/USegmentType.java b/src/net/sourceforge/plantuml/ugraphic/USegmentType.java new file mode 100644 index 000000000..d01d54094 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/USegmentType.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import java.awt.geom.PathIterator; +import java.util.EnumSet; + +public enum USegmentType { + + SEG_MOVETO(PathIterator.SEG_MOVETO), SEG_LINETO(PathIterator.SEG_LINETO), SEG_QUADTO(PathIterator.SEG_QUADTO), SEG_CUBICTO( + PathIterator.SEG_CUBICTO), SEG_CLOSE(PathIterator.SEG_CLOSE); + + private final int code; + + private USegmentType(int code) { + this.code = code; + } + + public static USegmentType getByCode(int code) { + for (USegmentType p : EnumSet.allOf(USegmentType.class)) { + if (p.code == code) { + return p; + } + } + throw new IllegalArgumentException(); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UShape.java b/src/net/sourceforge/plantuml/ugraphic/UShape.java new file mode 100644 index 000000000..1a4d1dfdc --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UShape.java @@ -0,0 +1,38 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +public interface UShape { + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UStroke.java b/src/net/sourceforge/plantuml/ugraphic/UStroke.java new file mode 100644 index 000000000..ccf104dbe --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UStroke.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5289 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +public class UStroke { + + private final int dash; + private final double thickness; + + public UStroke(int dash, double thickness) { + this.dash = dash; + this.thickness = thickness; + } + + public UStroke(double thickness) { + this(0, thickness); + } + + public UStroke() { + this(1.0); + } + + public int getDash() { + return dash; + } + + public double getThickness() { + return thickness; + } + + public String getDasharraySvg() { + if (dash == 0) { + return null; + } + return "" + dash + "," + dash; + } + + public String getDasharrayEps() { + if (dash == 0) { + return null; + } + return "" + dash + " " + (2*dash); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/UText.java b/src/net/sourceforge/plantuml/ugraphic/UText.java new file mode 100644 index 000000000..d8e815d06 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/UText.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic; + +import net.sourceforge.plantuml.graphic.FontConfiguration; + +public class UText implements UShape { + + private final String text; + private final FontConfiguration font; + + public UText(String text, FontConfiguration font) { + this.text = text; + this.font = font; + } + + public String getText() { + return text; + } + + public FontConfiguration getFontConfiguration() { + return font; + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java new file mode 100644 index 000000000..53fa2ee9d --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverEllipseEps.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverEllipseEps implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, EpsGraphics eps) { + final UEllipse rect = (UEllipse) ushape; + final double width = rect.getWidth(); + final double height = rect.getHeight(); + + eps.setFillColor(param.getBackcolor()); + eps.setStrokeColor(param.getColor()); + eps.setStrokeWidth(""+param.getStroke().getThickness(), param.getStroke().getDasharraySvg()); + + eps.epsEllipse(x + width / 2, y + height / 2, width / 2, height / 2); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java new file mode 100644 index 000000000..188c84ddc --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverImageEps.java @@ -0,0 +1,47 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverImageEps implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, EpsGraphics eps) { + final UImage shape = (UImage) ushape; + eps.drawImage(shape.getImage(), x, y); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java new file mode 100644 index 000000000..f30bd92f1 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverLineEps.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverLineEps implements UDriver { + + private final ClipContainer clipContainer; + + public DriverLineEps(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, EpsGraphics eps) { + final ULine shape = (ULine) ushape; + + final UClip clip = clipContainer.getClip(); + + if (clip != null) { + if (clip.isInside(x, y) == false) { + return; + } + if (clip.isInside(x + shape.getDX(), y + shape.getDY()) == false) { + return; + } + } + + //final String color = param.getColor() == null ? "none" : HtmlColor.getAsHtml(param.getColor()); + eps.setStrokeColor(param.getColor()); + eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDasharrayEps()); + eps.epsLine(x, y, x + shape.getDX(), y + shape.getDY()); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverPolygonEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverPolygonEps.java new file mode 100644 index 000000000..59bf4926f --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverPolygonEps.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverPolygonEps implements UDriver { + + private final ClipContainer clipContainer; + + public DriverPolygonEps(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, EpsGraphics eps) { + final UPolygon shape = (UPolygon) ushape; + + final double points[] = new double[shape.getPoints().size() * 2]; + int i = 0; + + for (Point2D pt : shape.getPoints()) { + points[i++] = pt.getX() + x; + points[i++] = pt.getY() + y; + } + + final UClip clip = clipContainer.getClip(); + + if (clip != null) { + for (int j = 0; j < points.length; j += 2) { + if (clip.isInside(points[j], points[j + 1]) == false) { + return; + } + } + } + + eps.setFillColor(param.getBackcolor()); + eps.setStrokeColor(param.getColor()); + + eps.epsPolygon(points); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java new file mode 100644 index 000000000..91527b49d --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import java.awt.Color; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UGradient; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverRectangleEps implements UDriver { + + private final ClipContainer clipContainer; + + public DriverRectangleEps(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, EpsGraphics eps) { + final URectangle rect = (URectangle) ushape; + + final double rx = rect.getRx(); + final double ry = rect.getRy(); + final double width = rect.getWidth(); + final double height = rect.getHeight(); + + final UGradient gr = param.getGradient(); + if (gr == null) { + eps.setStrokeColor(param.getColor()); + eps.setFillColor(param.getBackcolor()); + eps.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDasharrayEps()); + eps.epsRectangle(x, y, width, height, rx / 2, ry / 2); + } else { + eps.epsRectangle(x, y, width, height, rx / 2, ry / 2, gr); + } + + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java new file mode 100644 index 000000000..c00c99983 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverTextEps.java @@ -0,0 +1,150 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.awt.geom.Dimension2D; +import java.awt.geom.PathIterator; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.FontStyle; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UText; +import net.sourceforge.plantuml.ugraphic.g2d.DriverTextG2d; + +public class DriverTextEps implements UDriver { + + private final StringBounder stringBounder; + private final ClipContainer clipContainer; + private final FontRenderContext fontRenderContext; + private final Graphics2D g2dummy; + + public DriverTextEps(Graphics2D g2dummy, ClipContainer clipContainer) { + this.stringBounder = StringBounderUtils.asStringBounder(g2dummy); + this.clipContainer = clipContainer; + this.fontRenderContext = g2dummy.getFontRenderContext(); + this.g2dummy = g2dummy; + } + + public void draw(UShape ushape, double x, double y, UParam param, EpsGraphics eps) { + + final UClip clip = clipContainer.getClip(); + if (clip != null && clip.isInside(x, y) == false) { + return; + } + + final UText shape = (UText) ushape; + final FontConfiguration fontConfiguration = shape.getFontConfiguration(); + final Font font = fontConfiguration.getFont(); + + final TextLayout t = new TextLayout(shape.getText(), font, fontRenderContext); + eps.setStrokeColor(fontConfiguration.getColor()); + drawPathIterator(eps, x, y, t.getOutline(null).getPathIterator(null)); + + if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) { + final Color extended = fontConfiguration.getExtendedColor(); + if (extended != null) { + eps.setStrokeColor(extended); + } + final Dimension2D dim = DriverTextG2d.calculateDimension(stringBounder, font, shape.getText()); + eps.setStrokeWidth("1.1", null); + eps.epsLine(x, y + 1.5, x + dim.getWidth(), y + 1.5); + eps.setStrokeWidth("1", null); + } + if (fontConfiguration.containsStyle(FontStyle.WAVE)) { + final Dimension2D dim = DriverTextG2d.calculateDimension(stringBounder, font, shape.getText()); + final int ypos = (int) (y + 2.5) - 1; + final Color extended = fontConfiguration.getExtendedColor(); + if (extended != null) { + eps.setStrokeColor(extended); + } + eps.setStrokeWidth("1.1", null); + for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) { + eps.epsLine(i, ypos - 0, i + 3, ypos + 1); + eps.epsLine(i + 3, ypos + 1, i + 6, ypos - 0); + } + eps.setStrokeWidth("1", null); + } + if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { + final Color extended = fontConfiguration.getExtendedColor(); + if (extended != null) { + eps.setStrokeColor(extended); + } + final Dimension2D dim = DriverTextG2d.calculateDimension(stringBounder, font, shape.getText()); + final FontMetrics fm = g2dummy.getFontMetrics(font); + final int ypos = (int) (y - fm.getDescent() - 0.5); + eps.setStrokeWidth("1.3", null); + eps.epsLine(x, ypos, x + dim.getWidth(), ypos); + eps.setStrokeWidth("1", null); + } + + } + + static void drawPathIterator(EpsGraphics eps, double x, double y, PathIterator path) { + + eps.newpath(); + final double coord[] = new double[6]; + while (path.isDone() == false) { + final int code = path.currentSegment(coord); + if (code == PathIterator.SEG_MOVETO) { + eps.moveto(coord[0] + x, coord[1] + y); + } else if (code == PathIterator.SEG_LINETO) { + eps.lineto(coord[0] + x, coord[1] + y); + } else if (code == PathIterator.SEG_CLOSE) { + eps.closepath(); + } else if (code == PathIterator.SEG_CUBICTO) { + eps.curveto(coord[0] + x, coord[1] + y, coord[2] + x, coord[3] + y, coord[4] + x, coord[5] + y); + } else if (code == PathIterator.SEG_QUADTO) { + eps.quadto(coord[0] + x, coord[1] + y, coord[2] + x, coord[3] + y); + } else { + throw new UnsupportedOperationException("code=" + code); + } + + path.next(); + } + + eps.fill(path.getWindingRule()); + + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java new file mode 100644 index 000000000..6684c3dbd --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/eps/UGraphicEps.java @@ -0,0 +1,130 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.eps; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.font.TextLayout; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; + +import net.sourceforge.plantuml.eps.EpsGraphics; +import net.sourceforge.plantuml.eps.EpsStrategy; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.UnusedSpace; +import net.sourceforge.plantuml.skin.UDrawable; +import net.sourceforge.plantuml.ugraphic.AbstractUGraphic; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UText; + +public class UGraphicEps extends AbstractUGraphic implements ClipContainer { + + final static Graphics2D imDummy = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB).createGraphics(); + private UClip clip; + + private final StringBounder stringBounder; + + public UGraphicEps(EpsStrategy strategy) { + this(strategy.creatEpsGraphics()); + } + + private UGraphicEps(EpsGraphics eps) { + super(eps); + stringBounder = StringBounderUtils.asStringBounder(imDummy); + registerDriver(URectangle.class, new DriverRectangleEps(this)); + registerDriver(UText.class, new DriverTextEps(imDummy, this)); + registerDriver(ULine.class, new DriverLineEps(this)); + registerDriver(UPolygon.class, new DriverPolygonEps(this)); + registerDriver(UEllipse.class, new DriverEllipseEps()); + registerDriver(UImage.class, new DriverImageEps()); + // registerDriver(UPath.class, new DriverPathSvg(this)); + } + + public void close() { + getEpsGraphics().close(); + } + + public String getEPSCode() { + return getEpsGraphics().getEPSCode(); + } + + public EpsGraphics getEpsGraphics() { + return this.getGraphicObject(); + } + + public StringBounder getStringBounder() { + return stringBounder; + } + + public void setClip(UClip clip) { + this.clip = clip; + } + + public UClip getClip() { + return clip; + } + + public void centerChar(double x, double y, char c, Font font) { + final UnusedSpace unusedSpace = UnusedSpace.getUnusedSpace(font, c); + + final double xpos = x - unusedSpace.getCenterX() - 0.5; + final double ypos = y - unusedSpace.getCenterY() - 0.5; + + final TextLayout t = new TextLayout("" + c, font, imDummy.getFontRenderContext()); + getGraphicObject().setStrokeColor(getParam().getColor()); + DriverTextEps.drawPathIterator(getGraphicObject(), xpos + getTranslateX(), ypos + getTranslateY(), t + .getOutline(null).getPathIterator(null)); + + } + + static public String getEpsString(UDrawable udrawable) throws IOException { + final UGraphicEps ug = new UGraphicEps(EpsStrategy.getDefault()); + udrawable.drawU(ug); + return ug.getEPSCode(); + } + + static public void copyEpsToFile(UDrawable udrawable, File f) throws IOException { + final PrintWriter pw = new PrintWriter(f); + pw.print(UGraphicEps.getEpsString(udrawable)); + pw.close(); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverDotPathG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverDotPathG2d.java new file mode 100644 index 000000000..bd3a81eda --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverDotPathG2d.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.Graphics2D; + +import net.sourceforge.plantuml.posimo.DotPath; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverDotPathG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + final DotPath shape = (DotPath) ushape; + DriverLineG2d.manageStroke(param, g2d); + + if (param.getColor() != null) { + g2d.setColor(param.getColor()); + shape.draw(g2d, x, y); + } + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverEllipseG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverEllipseG2d.java new file mode 100644 index 000000000..53c8f727e --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverEllipseG2d.java @@ -0,0 +1,77 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 4984 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Arc2D; +import java.awt.geom.Ellipse2D; + +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverEllipseG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + final UEllipse shape = (UEllipse) ushape; + g2d.setStroke(new BasicStroke((float) param.getStroke().getThickness())); + if (shape.getStart() == 0 && shape.getExtend() == 0) { + final Shape ellipse = new Ellipse2D.Double(x, y, shape.getWidth(), shape.getHeight()); + + if (param.getBackcolor() != null) { + g2d.setColor(param.getBackcolor()); + g2d.fill(ellipse); + } + if (param.getColor() != null) { + g2d.setColor(param.getColor()); + g2d.draw(ellipse); + } + } else { + final Shape arc = new Arc2D.Double(x, y, shape.getWidth(), shape.getHeight(), shape.getStart(), shape + .getExtend(), Arc2D.OPEN); + if (param.getColor() != null) { + g2d.setColor(param.getBackcolor()); + g2d.fill(arc); + } + if (param.getColor() != null) { + g2d.setColor(param.getColor()); + g2d.draw(arc); + } + } + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverImageG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverImageG2d.java new file mode 100644 index 000000000..db02471a4 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverImageG2d.java @@ -0,0 +1,50 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3961 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.Graphics2D; + +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverImageG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + final UImage shape = (UImage) ushape; + g2d.drawImage(shape.getImage(), (int) x, (int) y, null); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverLineG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverLineG2d.java new file mode 100644 index 000000000..315d0b908 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverLineG2d.java @@ -0,0 +1,69 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5546 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Line2D; + +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UStroke; + +public class DriverLineG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + final ULine shape = (ULine) ushape; + + final Shape line = new Line2D.Double(x, y, x + shape.getDX(), y + shape.getDY()); + manageStroke(param, g2d); + g2d.setColor(param.getColor()); + g2d.draw(line); + } + + static void manageStroke(UParam param, Graphics2D g2d) { + final UStroke stroke = param.getStroke(); + final float thickness = (float) stroke.getThickness(); + if (stroke.getDash() == 0) { + g2d.setStroke(new BasicStroke(thickness)); + } else { + final float dash = (float) stroke.getDash(); + final float[] style = { dash, dash }; + g2d.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, style, 0)); + } + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverPolygonG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverPolygonG2d.java new file mode 100644 index 000000000..24b6a0fd0 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverPolygonG2d.java @@ -0,0 +1,67 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3837 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.BasicStroke; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverPolygonG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + final UPolygon shape = (UPolygon) ushape; + + final Polygon polygon = new Polygon(); + g2d.setStroke(new BasicStroke((float) param.getStroke().getThickness())); + + for (Point2D pt : shape.getPoints()) { + polygon.addPoint((int) (pt.getX() + x), (int) (pt.getY() + y)); + } + + if (param.getBackcolor() != null) { + g2d.setColor(param.getBackcolor()); + g2d.fill(polygon); + } + if (param.getColor() != null) { + g2d.setColor(param.getColor()); + g2d.draw(polygon); + } + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverRectangleG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverRectangleG2d.java new file mode 100644 index 000000000..6bad0da04 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverRectangleG2d.java @@ -0,0 +1,80 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 3914 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.BasicStroke; +import java.awt.GradientPaint; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; + +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UGradient; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverRectangleG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + g2d.setStroke(new BasicStroke((float) param.getStroke().getThickness())); + final URectangle shape = (URectangle) ushape; + final double rx = shape.getRx(); + final double ry = shape.getRy(); + final Shape rect; + if (rx == 0 && ry == 0) { + rect = new Rectangle2D.Double(x, y, shape.getWidth(), shape.getHeight()); + } else { + rect = new RoundRectangle2D.Double(x, y, shape.getWidth(), shape.getHeight(), rx, ry); + } + final UGradient gr = param.getGradient(); + if (gr == null) { + if (param.getBackcolor() != null) { + g2d.setColor(param.getBackcolor()); + g2d.fill(rect); + } + if (param.getColor() != null) { + g2d.setColor(param.getColor()); + g2d.draw(rect); + } + } else { + final GradientPaint paint = new GradientPaint((float) x, (float) y, gr.getColor1(), (float) (x + shape + .getWidth()), (float) (y + shape.getHeight()), gr.getColor2()); + g2d.setPaint(paint); + g2d.fill(rect); + } + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java new file mode 100644 index 000000000..56361b023 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java @@ -0,0 +1,109 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5507 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.FontStyle; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UText; + +public class DriverTextG2d implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { + final UText shape = (UText) ushape; + final FontConfiguration fontConfiguration = shape.getFontConfiguration(); + final Font font = fontConfiguration.getFont(); + g2d.setFont(font); + g2d.setColor(fontConfiguration.getColor()); + g2d.drawString(shape.getText(), (float) x, (float) y); + + if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) { + final Color extended = fontConfiguration.getExtendedColor(); + if (extended != null) { + g2d.setColor(extended); + } + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final int ypos = (int) (y + 2.5); + g2d.setStroke(new BasicStroke((float) 1.3)); + g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos); + g2d.setStroke(new BasicStroke()); + } + if (fontConfiguration.containsStyle(FontStyle.WAVE)) { + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final int ypos = (int) (y + 2.5) - 1; + final Color extended = fontConfiguration.getExtendedColor(); + if (extended != null) { + g2d.setColor(extended); + } + for (int i = (int) x; i < x + dim.getWidth() - 5; i += 6) { + g2d.drawLine(i, ypos - 0, i + 3, ypos + 1); + g2d.drawLine(i + 3, ypos + 1, i + 6, ypos - 0); + } + } + if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { + final Dimension2D dim = calculateDimension(StringBounderUtils.asStringBounder(g2d), font, shape.getText()); + final FontMetrics fm = g2d.getFontMetrics(font); + final int ypos = (int) (y - fm.getDescent() - 0.5); + final Color extended = fontConfiguration.getExtendedColor(); + if (extended != null) { + g2d.setColor(extended); + } + g2d.setStroke(new BasicStroke((float) 1.5)); + g2d.drawLine((int) x, ypos, (int) (x + dim.getWidth()), ypos); + g2d.setStroke(new BasicStroke()); + } + } + + static public Dimension2D calculateDimension(StringBounder stringBounder, Font font, String text) { + final Dimension2D rect = stringBounder.calculateDimension(font, text); + double h = rect.getHeight(); + if (h < 10) { + h = 10; + } + return new Dimension2DDouble(rect.getWidth(), h); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java new file mode 100644 index 000000000..a482a1826 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java @@ -0,0 +1,112 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5326 $ + * + */ +package net.sourceforge.plantuml.ugraphic.g2d; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.IOException; + +import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMaker; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.UnusedSpace; +import net.sourceforge.plantuml.posimo.DotPath; +import net.sourceforge.plantuml.skin.UDrawable; +import net.sourceforge.plantuml.ugraphic.AbstractUGraphic; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UText; +import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; + +public class UGraphicG2d extends AbstractUGraphic { + + private final BufferedImage bufferedImage; + + public UGraphicG2d(Graphics2D g2d, BufferedImage bufferedImage) { + super(g2d); + this.bufferedImage = bufferedImage; + registerDriver(URectangle.class, new DriverRectangleG2d()); + registerDriver(UText.class, new DriverTextG2d()); + registerDriver(ULine.class, new DriverLineG2d()); + registerDriver(UPolygon.class, new DriverPolygonG2d()); + registerDriver(UEllipse.class, new DriverEllipseG2d()); + registerDriver(UImage.class, new DriverImageG2d()); + registerDriver(DotPath.class, new DriverDotPathG2d()); + } + + public StringBounder getStringBounder() { + return StringBounderUtils.asStringBounder(getGraphicObject()); + } + + public final BufferedImage getBufferedImage() { + return bufferedImage; + } + + public void setClip(UClip uclip) { + if (uclip == null) { + getGraphicObject().setClip(null); + } else { + final Shape clip = new Rectangle2D.Double(uclip.getX() + getTranslateX(), uclip.getY() + getTranslateY(), + uclip.getWidth(), uclip.getHeight()); + getGraphicObject().setClip(clip); + } + } + + public void centerChar(double x, double y, char c, Font font) { + final UnusedSpace unusedSpace = UnusedSpace.getUnusedSpace(font, c); + + getGraphicObject().setColor(getParam().getColor()); + final double xpos = x - unusedSpace.getCenterX(); + final double ypos = y - unusedSpace.getCenterY() - 0.5; + + getGraphicObject().setFont(font); + getGraphicObject().drawString("" + c, (float) (xpos + getTranslateX()), (float) (ypos + getTranslateY())); + //getGraphicObject().drawString("" + c, Math.round(xpos + getTranslateX()), Math.round(ypos + getTranslateY())); + } + + static public String getSvgString(UDrawable udrawable) throws IOException { + final UGraphicSvg ug = new UGraphicSvg(false); + udrawable.drawU(ug); + return CucaDiagramFileMaker.getSvg(ug); + } + + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverEllipseSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverEllipseSvg.java new file mode 100644 index 000000000..047a09b2f --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverEllipseSvg.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverEllipseSvg implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + final UEllipse rect = (UEllipse) ushape; + final double width = rect.getWidth(); + final double height = rect.getHeight(); + + final String color = param.getColor() == null ? "none" : HtmlColor.getAsHtml(param.getColor()); + final String backcolor = param.getBackcolor() == null ? "none" : HtmlColor.getAsHtml(param.getBackcolor()); + + svg.setFillColor(backcolor); + svg.setStrokeColor(color); + svg.setStrokeWidth(""+param.getStroke().getThickness(), param.getStroke().getDasharraySvg()); + + svg.svgEllipse(x + width / 2, y + height / 2, width / 2, height / 2); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverImageSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverImageSvg.java new file mode 100644 index 000000000..e7f965007 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverImageSvg.java @@ -0,0 +1,45 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverImageSvg implements UDriver { + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + // Not supported + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverLineSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverLineSvg.java new file mode 100644 index 000000000..b5ff8a141 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverLineSvg.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverLineSvg implements UDriver { + + private final ClipContainer clipContainer; + + public DriverLineSvg(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + final ULine shape = (ULine) ushape; + + final UClip clip = clipContainer.getClip(); + + if (clip != null) { + if (clip.isInside(x, y) == false) { + return; + } + if (clip.isInside(x + shape.getDX(), y + shape.getDY()) == false) { + return; + } + } + + // svg.setStroke(new BasicStroke((float) + // param.getStroke().getThickness())); + final String color = param.getColor() == null ? "none" : HtmlColor.getAsHtml(param.getColor()); + svg.setStrokeColor(color); + svg.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDasharraySvg()); + svg.svgLine(x, y, x + shape.getDX(), y + shape.getDY()); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverPathSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverPathSvg.java new file mode 100644 index 000000000..62c315c47 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverPathSvg.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UPath; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverPathSvg implements UDriver { + + private final ClipContainer clipContainer; + + public DriverPathSvg(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + final UPath shape = (UPath) ushape; + + svg.svgPath(x, y, shape); + + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverPolygonSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverPolygonSvg.java new file mode 100644 index 000000000..f0b33c507 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverPolygonSvg.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverPolygonSvg implements UDriver { + + private final ClipContainer clipContainer; + + public DriverPolygonSvg(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + final UPolygon shape = (UPolygon) ushape; + + final double points[] = new double[shape.getPoints().size() * 2]; + int i = 0; + + for (Point2D pt : shape.getPoints()) { + points[i++] = pt.getX() + x; + points[i++] = pt.getY() + y; + } + + final UClip clip = clipContainer.getClip(); + + if (clip != null) { + for (int j = 0; j < points.length; j += 2) { + if (clip.isInside(points[j], points[j + 1]) == false) { + return; + } + } + } + + final String color = param.getColor() == null ? "none" : HtmlColor.getAsHtml(param.getColor()); + final String backcolor = param.getBackcolor() == null ? "none" : HtmlColor.getAsHtml(param.getBackcolor()); + + svg.setFillColor(backcolor); + svg.setStrokeColor(color); + svg.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDasharraySvg()); + + svg.svgPolygon(points); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverRectangleSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverRectangleSvg.java new file mode 100644 index 000000000..c469afc2e --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverRectangleSvg.java @@ -0,0 +1,90 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import java.awt.geom.Rectangle2D; + +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UGradient; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UShape; + +public class DriverRectangleSvg implements UDriver { + + private final ClipContainer clipContainer; + + public DriverRectangleSvg(ClipContainer clipContainer) { + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + final URectangle rect = (URectangle) ushape; + + final double rx = rect.getRx(); + final double ry = rect.getRy(); + double width = rect.getWidth(); + double height = rect.getHeight(); + + final UGradient gr = param.getGradient(); + if (gr == null) { + final String color = param.getColor() == null ? "none" : HtmlColor.getAsHtml(param.getColor()); + final String backcolor = param.getBackcolor() == null ? "none" : HtmlColor.getAsHtml(param.getBackcolor()); + svg.setFillColor(backcolor); + svg.setStrokeColor(color); + } else { + final String id = svg.createSvgGradient(HtmlColor.getAsHtml(gr.getColor1()), HtmlColor.getAsHtml(gr + .getColor2())); + svg.setFillColor("url(#" + id + ")"); + svg.setStrokeColor(null); + } + + svg.setStrokeWidth("" + param.getStroke().getThickness(), param.getStroke().getDasharraySvg()); + + final UClip clip = clipContainer.getClip(); + + if (clip != null) { + Rectangle2D.Double r = new Rectangle2D.Double(x, y, width, height); + r = clip.getClippedRectangle(r); + x = r.x; + y = r.y; + width = r.width; + height = r.height; + } + + svg.svgRectangle(x, y, width, height, rx / 2, ry / 2); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextAsPathSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextAsPathSvg.java new file mode 100644 index 000000000..7ab91ac70 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextAsPathSvg.java @@ -0,0 +1,101 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import java.awt.Font; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.awt.geom.PathIterator; + +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UText; + +public class DriverTextAsPathSvg implements UDriver { + + private final FontRenderContext fontRenderContext; + private final ClipContainer clipContainer; + + public DriverTextAsPathSvg(FontRenderContext fontRenderContext, ClipContainer clipContainer) { + this.fontRenderContext = fontRenderContext; + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + + final UClip clip = clipContainer.getClip(); + if (clip != null && clip.isInside(x, y) == false) { + return; + } + + final UText shape = (UText) ushape; + final FontConfiguration fontConfiguration = shape.getFontConfiguration(); + final Font font = fontConfiguration.getFont(); + + final TextLayout t = new TextLayout(shape.getText(), font, fontRenderContext); + drawPathIterator(svg, x, y, t.getOutline(null).getPathIterator(null)); + + } + + static void drawPathIterator(SvgGraphics svg, double x, double y, PathIterator path) { + + svg.newpath(); + final double coord[] = new double[6]; + while (path.isDone() == false) { + final int code = path.currentSegment(coord); + if (code == PathIterator.SEG_MOVETO) { + svg.moveto(coord[0] + x, coord[1] + y); + } else if (code == PathIterator.SEG_LINETO) { + svg.lineto(coord[0] + x, coord[1] + y); + } else if (code == PathIterator.SEG_CLOSE) { + svg.closepath(); + } else if (code == PathIterator.SEG_CUBICTO) { + svg.curveto(coord[0] + x, coord[1] + y, coord[2] + x, coord[3] + y, coord[4] + x, coord[5] + y); + } else if (code == PathIterator.SEG_QUADTO) { + svg.quadto(coord[0] + x, coord[1] + y, coord[2] + x, coord[3] + y); + } else { + throw new UnsupportedOperationException("code=" + code); + } + + path.next(); + } + + svg.fill(path.getWindingRule()); + + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java new file mode 100644 index 000000000..01ec9e8d7 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import java.awt.Font; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.FontStyle; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UDriver; +import net.sourceforge.plantuml.ugraphic.UParam; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UText; + +public class DriverTextSvg implements UDriver { + + private final StringBounder stringBounder; + private final ClipContainer clipContainer; + + public DriverTextSvg(StringBounder stringBounder, ClipContainer clipContainer) { + this.stringBounder = stringBounder; + this.clipContainer = clipContainer; + } + + public void draw(UShape ushape, double x, double y, UParam param, SvgGraphics svg) { + + final UClip clip = clipContainer.getClip(); + if (clip != null && clip.isInside(x, y) == false) { + return; + } + + final UText shape = (UText) ushape; + final FontConfiguration fontConfiguration = shape.getFontConfiguration(); + final Font font = fontConfiguration.getFont(); + String fontWeight = null; + if (fontConfiguration.containsStyle(FontStyle.BOLD) || font.isBold()) { + fontWeight = "bold"; + } + String fontStyle = null; + if (fontConfiguration.containsStyle(FontStyle.ITALIC) || font.isItalic()) { + fontStyle = "italic"; + } + String textDecoration = null; + if (fontConfiguration.containsStyle(FontStyle.UNDERLINE)) { + textDecoration = "underline"; + } else if (fontConfiguration.containsStyle(FontStyle.STRIKE)) { + textDecoration = "line-through"; + } + + svg.setFillColor(HtmlColor.getAsHtml(fontConfiguration.getColor())); + String text = shape.getText(); + if (text.startsWith(" ")) { + final double space = stringBounder.calculateDimension(font, " ").getWidth(); + while (text.startsWith(" ")) { + x += space; + text = text.substring(1); + } + } + text = text.trim(); + final Dimension2D dim = stringBounder.calculateDimension(font, text); + svg.text(text, x, y, font.getFamily(), font.getSize(), fontWeight, fontStyle, textDecoration, dim.getWidth()); + } +} diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java new file mode 100644 index 000000000..35afcf9ce --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -0,0 +1,134 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.svg; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.font.TextLayout; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; + +import javax.xml.transform.TransformerException; + +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.StringBounderUtils; +import net.sourceforge.plantuml.graphic.UnusedSpace; +import net.sourceforge.plantuml.svg.SvgGraphics; +import net.sourceforge.plantuml.ugraphic.AbstractUGraphic; +import net.sourceforge.plantuml.ugraphic.ClipContainer; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UEllipse; +import net.sourceforge.plantuml.ugraphic.UImage; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UPath; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UText; + +public class UGraphicSvg extends AbstractUGraphic implements ClipContainer { + + final static Graphics2D imDummy = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB).createGraphics(); + private UClip clip; + + private final StringBounder stringBounder; + + public UGraphicSvg(String backcolor, boolean textAsPath) { + this(new SvgGraphics(backcolor), textAsPath); + } + + public UGraphicSvg(boolean textAsPath) { + this(new SvgGraphics(), textAsPath); + } + + private UGraphicSvg(SvgGraphics svg, boolean textAsPath) { + super(svg); + stringBounder = StringBounderUtils.asStringBounder(imDummy); + registerDriver(URectangle.class, new DriverRectangleSvg(this)); + textAsPath = false; + if (textAsPath) { + registerDriver(UText.class, new DriverTextAsPathSvg(imDummy.getFontRenderContext(), this)); + } else { + registerDriver(UText.class, new DriverTextSvg(getStringBounder(), this)); + } + registerDriver(ULine.class, new DriverLineSvg(this)); + registerDriver(UPolygon.class, new DriverPolygonSvg(this)); + registerDriver(UEllipse.class, new DriverEllipseSvg()); + registerDriver(UImage.class, new DriverImageSvg()); + registerDriver(UPath.class, new DriverPathSvg(this)); + } + + public SvgGraphics getSvgGraphics() { + return this.getGraphicObject(); + } + + public StringBounder getStringBounder() { + return stringBounder; + } + + public void createXml(OutputStream os) throws IOException { + try { + getGraphicObject().createXml(os); + } catch (TransformerException e) { + throw new IOException(e.toString()); + } + } + + public void setClip(UClip clip) { + this.clip = clip == null ? null : clip.translate(getTranslateX(), getTranslateY()); + } + + public UClip getClip() { + return clip; + } + + public void centerCharOld(double x, double y, char c, Font font) { + final UText uText = new UText("" + c, new FontConfiguration(font, getParam().getColor())); + final UnusedSpace unusedSpace = UnusedSpace.getUnusedSpace(font, c); + draw(x - unusedSpace.getCenterX() + getTranslateX(), y - unusedSpace.getCenterY() + getTranslateY(), uText); + } + + public void centerChar(double x, double y, char c, Font font) { + final UnusedSpace unusedSpace = UnusedSpace.getUnusedSpace(font, c); + + final double xpos = x - unusedSpace.getCenterX() - 0.5; + final double ypos = y - unusedSpace.getCenterY() - 0.5; + + final TextLayout t = new TextLayout("" + c, font, imDummy.getFontRenderContext()); + getGraphicObject().setStrokeColor(HtmlColor.getAsHtml(getParam().getColor())); + DriverTextAsPathSvg.drawPathIterator(getGraphicObject(), xpos + getTranslateX(), ypos + getTranslateY(), t + .getOutline(null).getPathIterator(null)); + } + +} diff --git a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java new file mode 100644 index 000000000..0d93a01e1 --- /dev/null +++ b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java @@ -0,0 +1,82 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.ugraphic.txt; + +import java.awt.Font; + +import net.sourceforge.plantuml.asciiart.UmlCharAreaImpl; +import net.sourceforge.plantuml.asciiart.UmlCharArea; +import net.sourceforge.plantuml.asciiart.TextStringBounder; +import net.sourceforge.plantuml.asciiart.TranslatedCharArea; +import net.sourceforge.plantuml.graphic.FontStyle; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.ugraphic.AbstractCommonUGraphic; +import net.sourceforge.plantuml.ugraphic.UClip; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UText; + +public class UGraphicTxt extends AbstractCommonUGraphic { + + private final UmlCharArea charArea = new UmlCharAreaImpl(); + private int lastPrint = 0; + + public StringBounder getStringBounder() { + return new TextStringBounder(); + } + + public void draw(double x, double y, UShape shape) { + if (shape instanceof UText) { + final UText txt = (UText) shape; + charArea.drawStringLR(txt.getText(), 0, lastPrint); + lastPrint++; + if (txt.getFontConfiguration().containsStyle(FontStyle.WAVE)) { + charArea.drawHLine('^', lastPrint, 0, txt.getText().length()); + lastPrint++; + } + return; + } + throw new UnsupportedOperationException(); + } + + public void setClip(UClip clip) { + // throw new UnsupportedOperationException(); + } + + public void centerChar(double x, double y, char c, Font font) { + throw new UnsupportedOperationException(); + } + + public final UmlCharArea getCharArea() { + return new TranslatedCharArea(charArea, (int) getTranslateX(), (int) getTranslateY()); + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/UsecaseDiagram.java b/src/net/sourceforge/plantuml/usecasediagram/UsecaseDiagram.java new file mode 100644 index 000000000..0fb21391d --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/UsecaseDiagram.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagramType; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Rankdir; + +public class UsecaseDiagram extends AbstractEntityDiagram { + + public UsecaseDiagram() { + setRankdir(Rankdir.TOP_TO_BOTTOM); + } + + @Override + public IEntity getOrCreateClass(String code) { + if (code.startsWith("(") && code.endsWith(")")) { + return getOrCreateEntity(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code), EntityType.USECASE); + } + if (code.startsWith(":") && code.endsWith(":")) { + return getOrCreateEntity(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code), EntityType.ACTOR); + } + return getOrCreateEntity(code, EntityType.ACTOR); + } + + @Override + public UmlDiagramType getUmlDiagramType() { + return UmlDiagramType.USECASE; + } + + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/UsecaseDiagramFactory.java b/src/net/sourceforge/plantuml/usecasediagram/UsecaseDiagramFactory.java new file mode 100644 index 000000000..b3a78a856 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/UsecaseDiagramFactory.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram; + +import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; +import net.sourceforge.plantuml.command.CommandCreateNote; +import net.sourceforge.plantuml.command.CommandEndPackage; +import net.sourceforge.plantuml.command.CommandMultilinesStandaloneNote; +import net.sourceforge.plantuml.command.CommandNoteEntity; +import net.sourceforge.plantuml.command.CommandPackage; +import net.sourceforge.plantuml.command.CommandPage; +import net.sourceforge.plantuml.usecasediagram.command.CommandCreateActor; +import net.sourceforge.plantuml.usecasediagram.command.CommandCreateActor2; +import net.sourceforge.plantuml.usecasediagram.command.CommandCreateUsecase; +import net.sourceforge.plantuml.usecasediagram.command.CommandCreateUsecase2; +import net.sourceforge.plantuml.usecasediagram.command.CommandLinkUsecase2; +import net.sourceforge.plantuml.usecasediagram.command.CommandMultilinesUsecaseNoteEntity; +import net.sourceforge.plantuml.usecasediagram.command.CommandRankDirUsecase; + +public class UsecaseDiagramFactory extends AbstractUmlSystemCommandFactory { + + private UsecaseDiagram system; + + public UsecaseDiagram getSystem() { + return system; + } + + @Override + protected void initCommands() { + system = new UsecaseDiagram(); + + addCommand(new CommandRankDirUsecase(system)); + addCommonCommands(system); + + addCommand(new CommandPage(system)); + //addCommand(new CommandLinkUsecase(system)); + addCommand(new CommandLinkUsecase2(system)); + + addCommand(new CommandPackage(system)); + addCommand(new CommandEndPackage(system)); + addCommand(new CommandNoteEntity(system)); + + addCommand(new CommandCreateNote(system)); + addCommand(new CommandCreateActor(system)); + addCommand(new CommandCreateActor2(system)); + addCommand(new CommandCreateUsecase(system)); + addCommand(new CommandCreateUsecase2(system)); + + addCommand(new CommandMultilinesUsecaseNoteEntity(system)); + addCommand(new CommandMultilinesStandaloneNote(system)); + } +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java new file mode 100644 index 000000000..e2571ec52 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandCreateActor extends SingleLineCommand { + + public CommandCreateActor(UsecaseDiagram usecaseDiagram) { + super( + usecaseDiagram, + "(?i)^(?:actor\\s+)?([\\p{L}0-9_.]+|:[^:]+:|\"[^\"]+\")\\s*(?:as\\s+:?([\\p{L}0-9_.]+):?)?(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + // final EntityType type = EntityType.ACTOR; + final String code; + final String display; + if (arg.get(1) == null) { + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + display = code; + } else { + display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + } + final String stereotype = arg.get(2); + final Entity entity = (Entity) getSystem().getOrCreateClass(code); + entity.setDisplay(display); + + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java new file mode 100644 index 000000000..7d554e963 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandCreateActor2 extends SingleLineCommand { + + public CommandCreateActor2(UsecaseDiagram usecaseDiagram) { + super(usecaseDiagram, + "(?i)^(?:actor\\s+)?([\\p{L}0-9_.]+)\\s+as\\s+(:[^:]+:|\"[^\"]+\")(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + // final EntityType type = EntityType.ACTOR; + final String code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + final String display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + final String stereotype = arg.get(2); + final Entity entity = (Entity) getSystem().getOrCreateClass(code); + entity.setDisplay(display); + + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java new file mode 100644 index 000000000..051d95a77 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java @@ -0,0 +1,84 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandCreateUsecase extends SingleLineCommand { + + public CommandCreateUsecase(UsecaseDiagram usecaseDiagram) { + super( + usecaseDiagram, + "(?i)^(?:usecase\\s+)?([\\p{L}0-9_.]+|\\([^)]+\\)|\"[^\"]+\")\\s*(?:as\\s+\\(?([\\p{L}0-9_.]+)\\)?)?(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final EntityType type = EntityType.USECASE; + final String code; + final String display; + if (arg.get(1) == null) { + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + display = code; + } else { + display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + } + + final String stereotype = arg.get(2); + final Entity entity = (Entity) getSystem().getOrCreateEntity(code, type); + entity.setDisplay(display); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java new file mode 100644 index 000000000..8608a7bf1 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandCreateUsecase2 extends SingleLineCommand { + + public CommandCreateUsecase2(UsecaseDiagram usecaseDiagram) { + super(usecaseDiagram, + "(?i)^(?:usecase\\s+)?([\\p{L}0-9_.]+|\\([^)]+\\))\\s*as\\s+(\"[^\"]+\"|\\([^)]+\\))(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); + } + + @Override + protected boolean isForbidden(String line) { + if (line.matches("^[\\p{L}0-9_.]+$")) { + return true; + } + return false; + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final EntityType type = EntityType.USECASE; + final String code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); + final String display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); + + final String stereotype = arg.get(2); + final Entity entity = (Entity) getSystem().getOrCreateEntity(code, type); + entity.setDisplay(display); + if (stereotype != null) { + entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + } + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase.java new file mode 100644 index 000000000..a2023369a --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase.java @@ -0,0 +1,158 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandLinkUsecase extends SingleLineCommand { + + private static final int FIRST_UC_AC_OR_GROUP = 0; + private static final int LEFT_TO_RIGHT = 1; + private static final int LEFT_TO_RIGHT_QUEUE = 2; + private static final int LEFT_TO_RIGHT_HEAD = 3; + private static final int RIGHT_TO_LEFT = 4; + private static final int RIGHT_TO_LEFT_HEAD = 5; + private static final int RIGHT_TO_LEFT_QUEUE = 6; + private static final int SECOND_UC_AC_OR_GROUP = 7; + private static final int LINK_LABEL = 8; + + public CommandLinkUsecase(UsecaseDiagram diagram) { + super( + diagram, + "(?i)^([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*" + + "(?:(" + + "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*|\\.+(?:left|right|up|down|le?|ri?|up?|do?)?\\.*)([\\]>]|\\|[>\\]])?" + + ")|(" + + "([\\[<]|[<\\[]\\|)?([=-]*(?:left|right|up|down|le?|ri?|up?|do?)?[=-]+|\\.*(?:left|right|up|down|le?|ri?|up?|do?)?\\.+)" + + "))" + "\\s*([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*(?::\\s*([^\"]+))?$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + if (getSystem().isGroup(arg.get(FIRST_UC_AC_OR_GROUP)) && getSystem().isGroup(arg.get(SECOND_UC_AC_OR_GROUP))) { + return executePackageLink(arg); + } + if (getSystem().isGroup(arg.get(FIRST_UC_AC_OR_GROUP)) || getSystem().isGroup(arg.get(SECOND_UC_AC_OR_GROUP))) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final IEntity cl1 = getSystem().getOrCreateClass(arg.get(FIRST_UC_AC_OR_GROUP)); + final IEntity cl2 = getSystem().getOrCreateClass(arg.get(SECOND_UC_AC_OR_GROUP)); + + final LinkType linkType = arg.get(LEFT_TO_RIGHT) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); + final String queue = StringUtils.manageQueueForCuca(arg.get(LEFT_TO_RIGHT) != null ? arg + .get(LEFT_TO_RIGHT_QUEUE) : arg.get(RIGHT_TO_LEFT_QUEUE)); + + Link link = new Link(cl1, cl2, linkType, arg.get(LINK_LABEL), queue.length()); + if (arg.get(LEFT_TO_RIGHT) != null) { + Direction direction = StringUtils.getQueueDirection(arg.get(LEFT_TO_RIGHT_QUEUE)); + if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + direction = direction.getInv(); + } + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + } + if (arg.get(RIGHT_TO_LEFT) != null) { + Direction direction = StringUtils.getQueueDirection(arg.get(RIGHT_TO_LEFT_QUEUE)); + if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + direction = direction.getInv(); + } + if (direction == Direction.RIGHT || direction == Direction.DOWN) { + link = link.getInv(); + } + } + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executePackageLink(List arg) { + final Group cl1 = getSystem().getGroup(arg.get(FIRST_UC_AC_OR_GROUP)); + final Group cl2 = getSystem().getGroup(arg.get(SECOND_UC_AC_OR_GROUP)); + + final LinkType linkType = arg.get(LEFT_TO_RIGHT) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); + final String queue = arg.get(LEFT_TO_RIGHT) != null ? arg.get(LEFT_TO_RIGHT_QUEUE) : arg + .get(RIGHT_TO_LEFT_QUEUE); + + final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get(LINK_LABEL), queue + .length()); + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private LinkType getLinkTypeNormal(List arg) { + final String queue = arg.get(LEFT_TO_RIGHT_QUEUE); + final String key = arg.get(LEFT_TO_RIGHT_HEAD); + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType; + } + + private LinkType getLinkTypeInv(List arg) { + final String queue = arg.get(RIGHT_TO_LEFT_QUEUE); + final String key = arg.get(RIGHT_TO_LEFT_HEAD); + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType.getInv(); + } + + private LinkType getLinkTypeFromKey(String k) { + if (k == null) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + if (k.equals("<") || k.equals(">")) { + return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); + } + if (k.equals("<|") || k.equals("|>")) { + return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java new file mode 100644 index 000000000..99cf91932 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java @@ -0,0 +1,219 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.Map; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; +import net.sourceforge.plantuml.cucadiagram.Group; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandLinkUsecase2 extends SingleLineCommand2 { + + private static final int FIRST_UC_AC_OR_GROUP = 0; + private static final int LEFT_TO_RIGHT = 1; + private static final int LEFT_TO_RIGHT_QUEUE = 2; + private static final int LEFT_TO_RIGHT_HEAD = 3; + private static final int RIGHT_TO_LEFT = 4; + private static final int RIGHT_TO_LEFT_HEAD = 5; + private static final int RIGHT_TO_LEFT_QUEUE = 6; + private static final int SECOND_UC_AC_OR_GROUP = 7; + private static final int LINK_LABEL = 8; + + public CommandLinkUsecase2(UsecaseDiagram diagram) { + super(diagram, getRegexConcat()); + // "(?i)^([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*" + // + "(?:(" + // + + // "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*|\\.+(?:left|right|up|down|le?|ri?|up?|do?)?\\.*)([\\]>]|\\|[>\\]])?" + // + ")|(" + // + + // "([\\[<]|[<\\[]\\|)?([=-]*(?:left|right|up|down|le?|ri?|up?|do?)?[=-]+|\\.*(?:left|right|up|down|le?|ri?|up?|do?)?\\.+)" + // + "))" + + // "\\s*([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*(?::\\s*([^\"]+))?$"); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), getGroup("ENT1"), new RegexLeaf("\\s*"), new RegexOr(new RegexLeaf( + "LEFT_TO_RIGHT", "(([-=.]+)(left|right|up|down|le?|ri?|up?|do?)?([-=.]*)([\\]>]|\\|[>\\]])?)"), + new RegexLeaf("RIGHT_TO_LEFT", + "(([\\[<]|[<\\[]\\|)?([-=.]*)(left|right|up|down|le?|ri?|up?|do?)?([-=.]+))")), new RegexLeaf( + "\\s*"), getGroup("ENT2"), new RegexLeaf("\\s*"), new RegexLeaf("LABEL_LINK", "(?::\\s*([^\"]+))?$")); + } + + private static RegexLeaf getGroup(String name) { + return new RegexLeaf(name, "([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))"); + } + + @Override + protected CommandExecutionResult executeArg(Map arg) { + final String ent1 = arg.get("ENT1").get(0); + final String ent2 = arg.get("ENT2").get(0); + + if (getSystem().isGroup(ent1) && getSystem().isGroup(ent2)) { + return executePackageLink(arg); + } + if (getSystem().isGroup(ent1) || getSystem().isGroup(ent2)) { + return CommandExecutionResult.error("Package can be only linked to other package"); + } + + final IEntity cl1 = getSystem().getOrCreateClass(ent1); + final IEntity cl2 = getSystem().getOrCreateClass(ent2); + + final LinkType linkType = getLinkType(arg); + Direction dir = getDirection(arg); + final String queue; + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + queue = "-"; + } else { + queue = getQueue(arg); + } + if (dir != null && linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + dir = dir.getInv(); + } + + Link link = new Link(cl1, cl2, linkType, arg.get("LABEL_LINK").get(0), queue.length()); + + if (dir == Direction.LEFT || dir == Direction.UP) { + link = link.getInv(); + } + + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult executePackageLink(Map arg) { + final String ent1 = arg.get("ENT1").get(0); + final String ent2 = arg.get("ENT2").get(0); + final Group cl1 = getSystem().getGroup(ent1); + final Group cl2 = getSystem().getGroup(ent2); + + final LinkType linkType = getLinkType(arg); + Direction dir = getDirection(arg); + final String queue; + if (dir == Direction.LEFT || dir == Direction.RIGHT) { + queue = "-"; + } else { + queue = getQueue(arg); + } + if (dir != null && linkType.isExtendsOrAgregationOrCompositionOrPlus()) { + dir = dir.getInv(); + } + + Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get("LABEL_LINK").get(0), + queue.length()); + if (dir == Direction.LEFT || dir == Direction.UP) { + link = link.getInv(); + } + getSystem().addLink(link); + return CommandExecutionResult.ok(); + } + + private String getQueue(Map arg) { + if (arg.get("LEFT_TO_RIGHT").get(1) != null) { + return arg.get("LEFT_TO_RIGHT").get(1).trim() + arg.get("LEFT_TO_RIGHT").get(3).trim(); + } + if (arg.get("RIGHT_TO_LEFT").get(2) != null) { + return arg.get("RIGHT_TO_LEFT").get(2).trim() + arg.get("RIGHT_TO_LEFT").get(4).trim(); + } + throw new IllegalArgumentException(); + } + + private Direction getDirection(Map arg) { + if (arg.get("LEFT_TO_RIGHT").get(2) != null) { + return StringUtils.getQueueDirection(arg.get("LEFT_TO_RIGHT").get(2)); + } + if (arg.get("RIGHT_TO_LEFT").get(3) != null) { + return StringUtils.getQueueDirection(arg.get("RIGHT_TO_LEFT").get(3)).getInv(); + } + return null; + } + + private LinkType getLinkType(Map arg) { + if (arg.get("LEFT_TO_RIGHT").get(0) != null) { + return getLinkTypeNormal(arg.get("LEFT_TO_RIGHT")); + } + if (arg.get("RIGHT_TO_LEFT").get(0) != null) { + return getLinkTypeInv(arg.get("RIGHT_TO_LEFT")); + } + throw new IllegalArgumentException(); + } + + private LinkType getLinkTypeNormal(RegexPartialMatch regexPartialMatch) { + final String queue = regexPartialMatch.get(1).trim() + regexPartialMatch.get(3).trim(); + final String key = regexPartialMatch.get(4); + return getLinkType(queue, key); + } + + private LinkType getLinkTypeInv(RegexPartialMatch regexPartialMatch) { + final String queue = regexPartialMatch.get(2).trim() + regexPartialMatch.get(4).trim(); + final String key = regexPartialMatch.get(1); + return getLinkType(queue, key).getInv(); + } + + private LinkType getLinkType(String queue, String key) { + if (key != null) { + key = key.trim(); + } + LinkType linkType = getLinkTypeFromKey(key); + + if (queue.startsWith(".")) { + linkType = linkType.getDashed(); + } + return linkType; + } + + private LinkType getLinkTypeFromKey(String k) { + if (k == null) { + return new LinkType(LinkDecor.NONE, LinkDecor.NONE); + } + if (k.equals("<") || k.equals(">")) { + return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); + } + if (k.equals("<|") || k.equals("|>")) { + return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandMultilinesUsecaseNoteEntity.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandMultilinesUsecaseNoteEntity.java new file mode 100644 index 000000000..c020213f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandMultilinesUsecaseNoteEntity.java @@ -0,0 +1,44 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import net.sourceforge.plantuml.command.AbstractCommandMultilinesNoteEntity; +import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; + +public class CommandMultilinesUsecaseNoteEntity extends AbstractCommandMultilinesNoteEntity { + + public CommandMultilinesUsecaseNoteEntity(final UsecaseDiagram system) { + super(system, + "(?i)^note\\s+(right|left|top|bottom)\\s+(?:of\\s+)?([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*(#\\w+)?$"); + } + +} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandRankDirUsecase.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandRankDirUsecase.java new file mode 100644 index 000000000..f196846f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandRankDirUsecase.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.usecasediagram.command; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.cucadiagram.Rankdir; + +public class CommandRankDirUsecase extends SingleLineCommand { + + public CommandRankDirUsecase(AbstractEntityDiagram diagram) { + super(diagram, "(?i)^(left to right|top to bottom)\\s+direction$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + final String s = arg.get(0).toUpperCase().replace(' ', '_'); + getSystem().setRankdir(Rankdir.valueOf(s)); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java new file mode 100644 index 000000000..a4779d95a --- /dev/null +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -0,0 +1,138 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.version; + +import java.awt.Color; +import java.awt.Font; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import javax.imageio.ImageIO; + +import net.sourceforge.plantuml.AbstractPSystem; +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.OptionPrint; +import net.sourceforge.plantuml.graphic.GraphicPosition; +import net.sourceforge.plantuml.graphic.GraphicStrings; + +public class PSystemVersion extends AbstractPSystem { + + private final List strings = new ArrayList(); + private final BufferedImage image; + + PSystemVersion(boolean withImage, List args) throws IOException { + strings.addAll(args); + if (withImage) { + final InputStream is = getClass().getResourceAsStream("logo.png"); + image = ImageIO.read(is); + is.close(); + } else { + image = null; + } + } + + public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + OutputStream os = null; + try { + os = new FileOutputStream(suggestedFile); + getGraphicStrings().writeImage(os, fileFormat); + } finally { + if (os != null) { + os.close(); + } + } + return Arrays.asList(suggestedFile); + } + + public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + getGraphicStrings().writeImage(os, fileFormat); + } + + public static PSystemVersion createShowVersion() throws IOException { + final List strings = new ArrayList(); + strings.add("PlantUML version " + Version.version() + " (" + new Date(Version.compileTime()) + ")"); + strings.add(" "); + + strings.addAll(OptionPrint.getTestDotStrings()); + strings.add(" "); + final Properties p = System.getProperties(); + strings.add(p.getProperty("java.runtime.name")); + strings.add(p.getProperty("java.vm.name")); + strings.add(p.getProperty("java.runtime.version")); + strings.add(p.getProperty("os.name")); + return new PSystemVersion(true, strings); + } + + public static PSystemVersion createShowAuthors() throws IOException { + final List strings = new ArrayList(); + strings.add("PlantUML version " + Version.version() + " (" + new Date(Version.compileTime()) + ")"); + strings.add(" "); + strings.add("Original idea: Arnaud Roques"); + strings.add("Word Macro: Alain Bertucat & Matthieu Sabatier"); + strings.add("Eclipse Plugin: Claude Durif & Anne Pecoil"); + strings.add("Site design: Raphael Cotisson"); + strings.add("Logo: Benjamin Croizet"); + + strings.add(" "); + strings.add("http://plantuml.sourceforge.net"); + strings.add(" "); + return new PSystemVersion(true, strings); + } + + public static PSystemVersion createTestDot() throws IOException { + final List strings = new ArrayList(); + strings.addAll(OptionPrint.getTestDotStrings()); + return new PSystemVersion(false, strings); + } + + private GraphicStrings getGraphicStrings() throws IOException { + final Font font = new Font("SansSerif", Font.PLAIN, 12); + return new GraphicStrings(strings, font, Color.BLACK, Color.WHITE, image, GraphicPosition.BACKGROUND_CORNER, + false); + // return new GraphicStrings(strings, font, Color.BLACK, Color.WHITE, + // false); + } + + public String getDescription() { + return "(Version)"; + } + +} diff --git a/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java b/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java new file mode 100644 index 000000000..9fac644b6 --- /dev/null +++ b/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * 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 + * + */ +package net.sourceforge.plantuml.version; + +import java.io.IOException; + +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.PSystemBasicFactory; + +public class PSystemVersionFactory implements PSystemBasicFactory { + + private PSystemVersion system; + + public PSystemVersionFactory() { + reset(); + } + + public void reset() { + } + + public boolean executeLine(String line) { + try { + if (line.matches("(?i)^(authors?|about)\\s*$")) { + system = PSystemVersion.createShowAuthors(); + return true; + } + if (line.matches("(?i)^version\\s*$")) { + system = PSystemVersion.createShowVersion(); + return true; + } + if (line.matches("(?i)^testdot\\s*$")) { + system = PSystemVersion.createTestDot(); + return true; + } + } catch (IOException e) { + Log.error("Error " + e); + + } + return false; + } + + public PSystemVersion getSystem() { + return system; + } + +} diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java new file mode 100644 index 000000000..889b345af --- /dev/null +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -0,0 +1,46 @@ +/* ======================================================================== + * 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 + * + * Revision $Revision: 5539 $ + * + */ +package net.sourceforge.plantuml.version; + +public class Version { + + public static int version() { + return 5538; + } + + public static long compileTime() { + return 1288721031328L; + } + +} diff --git a/src/net/sourceforge/plantuml/version/logo.png b/src/net/sourceforge/plantuml/version/logo.png new file mode 100644 index 000000000..986cf4e75 Binary files /dev/null and b/src/net/sourceforge/plantuml/version/logo.png differ