Gridarta Editor
AbstractArchetypeBuilder.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.model.archetype;
21 
22 import java.util.LinkedHashMap;
23 import java.util.Map;
24 import java.util.Map.Entry;
32 import org.jetbrains.annotations.NotNull;
33 import org.jetbrains.annotations.Nullable;
34 
40 public abstract class AbstractArchetypeBuilder<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> {
41 
46  @Nullable
47  private R prototype;
48 
52  @Nullable
54 
59  @Nullable
60  private R archetype;
61 
65  @NotNull
66  private final Map<String, String> attributes = new LinkedHashMap<>();
67 
72  @NotNull
74 
80  protected AbstractArchetypeBuilder(@NotNull final GameObjectFactory<G, A, R> gameObjectFactory) {
81  this.gameObjectFactory = gameObjectFactory;
82  }
83 
90  public void init(@Nullable final R prototype, @NotNull final ErrorViewCollector errorViewCollector) {
91  this.prototype = prototype;
92  this.errorViewCollector = errorViewCollector;
93  // start with new clean GameObject instance
94  if (prototype == null) {
95  archetype = gameObjectFactory.newArchetype(""); // XXX: undefined archetype name
96  } else {
97  archetype = prototype.clone();
98  }
99  attributes.clear();
100  }
101 
102  public void reInit(@NotNull final String archetypeName) {
103  if (archetype == null) {
104  archetype = gameObjectFactory.newArchetype(archetypeName);
105  } else {
106  archetype.setArchetypeName(archetypeName);
107  }
108  attributes.clear();
109  }
110 
111  public void setMsgText(@NotNull final String msgText) {
112  if (archetype == null) {
113  throw new IllegalStateException();
114  }
115  archetype.setMsgText(msgText);
116  }
117 
118  @NotNull
119  public String getArchetypeName() {
120  if (archetype == null) {
121  throw new IllegalStateException();
122  }
123  return archetype.getArchetypeName();
124  }
125 
126  public void addObjectText(@NotNull final String line) {
127  if (archetype == null) {
128  throw new IllegalStateException();
129  }
130  if (errorViewCollector == null) {
131  throw new IllegalStateException();
132  }
133 
134  if (line.indexOf('\n') != -1) {
135  throw new IllegalArgumentException();
136  }
137 
138  final String[] tmp = StringUtils.PATTERN_SPACES.split(line, 2);
139  final String key = tmp[0];
140  if (tmp.length < 2) {
141  assert archetype != null;
142  final String archetypeName = archetype.getArchetypeName();
143  assert errorViewCollector != null;
144  errorViewCollector.addWarning(ErrorViewCategory.ARCHETYPE_INVALID, archetypeName + ": invalid attribute definition: " + line);
145  return;
146  }
147  final String value = tmp[1];
148  final String previousValue = attributes.put(key, value);
149  if (previousValue != null) {
150  assert archetype != null;
151  final String archetypeName = archetype.getArchetypeName();
152  assert errorViewCollector != null;
153  errorViewCollector.addWarning(ErrorViewCategory.ARCHETYPE_INVALID, archetypeName + ": duplicate attribute definition: " + line + ", previous value was " + previousValue);
154  }
155  }
156 
157  public void addLast(@NotNull final G invObject) {
158  if (archetype == null) {
159  throw new IllegalStateException();
160  }
161  archetype.addLast(invObject);
162  }
163 
169  @NotNull
170  public R finish() {
171  if (prototype != null && prototype.getAttributeString(BaseObject.NAME).isEmpty() && !attributes.containsKey(BaseObject.NAME)) {
172  assert prototype != null;
173  addObjectText(BaseObject.NAME + " " + prototype.getArchetypeName());
174  }
175 
176  if (archetype == null) {
177  throw new IllegalStateException();
178  }
179  final R result = archetype;
180  final StringBuilder sb = new StringBuilder();
181  archetype = null;
182  for (final String attribute : StringUtils.PATTERN_END_OF_LINE.split(result.getObjectText())) {
183  final String[] tmp = StringUtils.PATTERN_SPACES.split(attribute, 2);
184  if (tmp.length == 2 && !attributes.containsKey(tmp[0])) {
185  sb.append(attribute).append('\n');
186  }
187  }
188  for (final Entry<String, String> attribute : attributes.entrySet()) {
189  sb.append(attribute.getKey()).append(' ').append(attribute.getValue()).append('\n');
190  }
191  result.setObjectText(sb.toString());
192  attributes.clear();
193  return result;
194  }
195 
196  public void setMultiX(final int multiX) {
197  if (archetype == null) {
198  throw new IllegalStateException();
199  }
200  archetype.setMultiX(multiX);
201  }
202 
203  public void setMultiY(final int multiY) {
204  if (archetype == null) {
205  throw new IllegalStateException();
206  }
207  archetype.setMultiY(multiY);
208  }
209 
213  @NotNull
214  protected R getArchetype() {
215  final R result = archetype;
216  if (result == null) {
217  throw new IllegalStateException();
218  }
219  return result;
220  }
221 
222 }
Utility class for string manipulation.
Convenience class for adding messages to a ErrorView instance using a fixed category name...
void addWarning(@NotNull final ErrorViewCategory category)
Adds a warning message.
static final Pattern PATTERN_SPACES
The pattern that matches a non-empty sequence of spaces.
Defines possible error categories for ErrorView instances.
final Map< String, String > attributes
Collected attributes.
void init(@Nullable final R prototype, @NotNull final ErrorViewCollector errorViewCollector)
Base package of all Gridarta classes.
Reflects a game object (object on a map).
Definition: GameObject.java:36
Abstract factory for creating GameObject instances.
final GameObjectFactory< G, A, R > gameObjectFactory
The GameObjectFactory for creating new Archetypes.
GameObjects are the objects based on Archetypes found on maps.
R newArchetype(@NotNull String archetypeName)
Creates a new Archetype instance.
AbstractArchetypeBuilder(@NotNull final GameObjectFactory< G, A, R > gameObjectFactory)
Creates a new instance.
ErrorViewCollector errorViewCollector
The ErrorViewCollector for reporting errors.
static final Pattern PATTERN_END_OF_LINE
The pattern to match end of line characters separating lines.
String NAME
The attribute name of the object&#39;s name.
Definition: BaseObject.java:60