20 package net.sf.gridarta.model.io;
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.util.List;
37 import net.
sf.japi.swing.action.ActionBuilder;
38 import net.
sf.japi.swing.action.ActionBuilderFactory;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
47 public abstract class AbstractArchetypeParser<G
extends GameObject<G, A, R>, A extends
MapArchObject<A>, R extends
Archetype<G, A, R>, B extends
AbstractArchetypeBuilder<G, A, R>> implements
ArchetypeParser<G, A, R> {
53 private static final ActionBuilder
ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder(
"net.sf.gridarta");
86 public void parseArchetypeFromStream(@NotNull
final BufferedReader in, @Nullable
final R prototype, @Nullable
final String line, @Nullable
final String archName, @NotNull
final String panelName, @NotNull
final String folderName, @NotNull
final String archPath, @NotNull
final List<G> invObjects, @NotNull
final ErrorViewCollector errorViewCollector)
throws IOException {
87 archetypeBuilder.init(prototype, errorViewCollector);
88 final boolean isInternPath;
90 @Nullable
final String path;
92 final String tmpPath = archPath +
"/";
93 isInternPath = tmpPath.startsWith(
"/intern/");
102 thisLine2 = in.readLine();
108 @Nullable R firstArch = null;
109 boolean archMore =
false;
111 boolean reportError =
true;
116 if (thisLine2 == null) {
120 final String thisLine = thisLine2.trim();
121 if (thisLine.startsWith(
"#") || thisLine.isEmpty()) {
122 thisLine2 = in.readLine();
126 if (thisLine.equals(
"More")) {
127 if (firstArch == null) {
128 firstArch = lastArch;
133 }
else if (!thisLine.isEmpty() && thisLine.charAt(0) !=
'#') {
140 thisLine2 = in.readLine();
143 final String archetypeName = archName != null ? archName : thisLine2.trim().substring(7);
144 archetypeBuilder.reInit(archetypeName);
146 if (firstArch != null) {
154 @NotNull String editorFolder = archPath.isEmpty() ?
"default" : archPath;
156 thisLine2 = in.readLine();
157 if (thisLine2 == null) {
162 final String thisLine = thisLine2.trim();
163 if (thisLine.startsWith(
"#") || thisLine.isEmpty()) {
167 if (
processLine(in, thisLine, thisLine2, archetypeBuilder, errorViewCollector, invObjects)) {
171 }
else if (thisLine.equals(
"end")) {
173 }
else if (thisLine.equals(
"msg")) {
175 }
else if (thisLine.equals(
"anim")) {
177 }
else if (thisLine.startsWith(
"visibility ")) {
179 }
else if (thisLine.startsWith(
"magicmap ")) {
181 }
else if (thisLine.startsWith(
"x ")) {
182 if (!archMore && !archetypeBuilder.getArchetypeName().equals(
START_ARCH_NAME)) {
183 errorViewCollector.addWarning(
ErrorViewCategory.
ARCHETYPE_INVALID, ACTION_BUILDER.format(
"logFoundCoordInDefArchSingleSquareOrHead",
"x", archetypeBuilder.getArchetypeName()));
184 archetypeBuilder.addObjectText(thisLine);
186 archetypeBuilder.setMultiX(Integer.parseInt(thisLine.substring(2)));
188 }
else if (thisLine.startsWith(
"y ")) {
189 if (!archMore && !archetypeBuilder.getArchetypeName().equals(
START_ARCH_NAME)) {
190 errorViewCollector.addWarning(
ErrorViewCategory.
ARCHETYPE_INVALID, ACTION_BUILDER.format(
"logFoundCoordInDefArchSingleSquareOrHead",
"y", archetypeBuilder.getArchetypeName()));
191 archetypeBuilder.addObjectText(thisLine);
193 archetypeBuilder.setMultiY(Integer.parseInt(thisLine.substring(2)));
195 }
else if (thisLine.startsWith(
"editor_folder ")) {
196 editorFolder = thisLine.substring(14).trim();
198 archetypeBuilder.addObjectText(thisLine);
202 final R archetype = archetypeBuilder.finish();
204 if (firstArch != null) {
205 firstArch.addTailPart(archetype);
206 }
else if (
addToPanel(isInternPath, editorFolder, archetype)) {
215 folder = names.length >= 2 ? names[1] : names[0];
217 archetype.setEditorFolder(panel +
"/" + folder);
230 if (archName != null) {
231 archetype.setArtifact();
232 if (prototype != null) {
237 lastArch = archetype;
240 thisLine2 = in.readLine();
243 if (firstArch != null) {
255 final StringBuilder msgText =
new StringBuilder();
258 final String thisLine2 = in.readLine();
259 if (thisLine2 == null) {
264 final String thisLine3 = thisLine2.trim();
265 if (thisLine3.equals(
"endmsg")) {
270 msgText.append(thisLine2).append(
"\n");
273 if (msgText.length() > 0) {
274 archetypeBuilder.setMsgText(msgText.toString());
285 private void parseAnim(@NotNull
final BufferedReader in, @NotNull
final ErrorViewCollector errorViewCollector, @NotNull
final String path)
throws IOException {
286 final StringBuilder animText =
new StringBuilder();
289 final String thisLine2 = in.readLine();
290 if (thisLine2 == null) {
295 final String thisLine3 = thisLine2.trim();
296 if (thisLine3.startsWith(
"#") || thisLine3.isEmpty()) {
300 if (thisLine3.equals(
"mina")) {
304 animText.append(thisLine3).append(
"\n");
307 final String animationName =
"_" + archetypeBuilder.getArchetypeName();
309 animationObjects.
addAnimationObject(animationName, animText.toString(), path + animationName);
327 protected abstract boolean isStartLine(@NotNull String line);
340 protected abstract boolean processLine(@NotNull BufferedReader in, @NotNull String line, @NotNull String line2, @NotNull B archetypeBuilder, @NotNull
ErrorViewCollector errorViewCollector, @NotNull List<G> invObjects)
throws IOException;
364 protected abstract boolean addToPanel(
boolean isInternPath, @NotNull String editorFolder, @NotNull R archetype);
Utility class for string manipulation.
abstract void initParseArchetype()
Called when a new archetype starts.
abstract boolean addToPanel(boolean isInternPath, @NotNull String editorFolder, @NotNull R archetype)
Returns whether an archetype should be added to the archetype chooser.
Convenience class for adding messages to a ErrorView instance using a fixed category name...
static final ActionBuilder ACTION_BUILDER
Action Builder.
Gridarta can handle frame information of animations and allow the selection of an animation using a t...
abstract boolean isStartLine(@NotNull String line)
Returns whether a give input line denotes the start of a new archetype.
final B archetypeBuilder
The AbstractArchetypeBuilder to use.
Exception thrown to indicate that an animation object is not acceptable.
String START_ARCH_NAME
Name of the system-archetype containing path of starting map.
Defines possible error categories for ErrorView instances.
Base package of all Gridarta classes.
Reflects a game object (object on a map).
final AnimationObjects animationObjects
The animation objects instance.
An Exception indicating that an Archetype name is not unique.
AnimationObjects is a container for AnimationObjects.
GameObjects are the objects based on Archetypes found on maps.
void parseArchetypeFromStream(@NotNull final BufferedReader in, @Nullable final R prototype, @Nullable final String line, @Nullable final String archName, @NotNull final String panelName, @NotNull final String folderName, @NotNull final String archPath, @NotNull final List< G > invObjects, @NotNull final ErrorViewCollector errorViewCollector)
AbstractArchetypeParser(@NotNull final B archetypeBuilder, @NotNull final AnimationObjects animationObjects, @NotNull final ArchetypeSet< G, A, R > archetypeSet)
Creates an ArchetypeParser.
void parseAnim(@NotNull final BufferedReader in, @NotNull final ErrorViewCollector errorViewCollector, @NotNull final String path)
Parses an "anim..mina" block.
Utility class for archetype attribute related functions.
abstract boolean processLine(@NotNull BufferedReader in, @NotNull String line, @NotNull String line2, @NotNull B archetypeBuilder, @NotNull ErrorViewCollector errorViewCollector, @NotNull List< G > invObjects)
Called for each processed line.
void addArchetype(@NotNull R archetype)
Adds an Archetype to this Set.
Creates Archetype instances.
String getPath()
Get the path of this AbstractNamedObject.
NamedObject getAnimationObject()
Returns the illegal animation object.
AnimationObject getDuplicate()
Get the duplicate that caused this exception.
static String diffArchTextKeys(@NotNull final BaseObject<?, ?, ?, ?> gameObject, @NotNull final BaseObject<?, ?, ?, ?> archetype)
Returns all attributes from the given game object that don't exist in an archetype.
Common interface for ArchetypeParsers.
abstract void finishParseArchetype(@NotNull R archetype)
Called after all parts of an archetype have been processed.
void parseMsg(@NotNull final BufferedReader in, @NotNull final ErrorViewCollector errorViewCollector)
Parses a "msg..endmsg" block.
Interface that captures similarities between different ArchetypeSet implementations.
boolean isLoadedFromArchive()
Returns whether the Archetypes in this ArchetypeSet were loaded from an archive.
Exception that's thrown in case an animation name was not unique.
Abstract base implementation of ArchetypeParser.
String EDITOR_FOLDER_INTERN
The editor folder name for server-internal archetypes.
void addAnimationObject(@NotNull String animName, @NotNull String list, @NotNull String path)
Add an animation object.
Interface for MapArchObjects.
final ArchetypeSet< G, A, R > archetypeSet
The ArchetypeSet to use.
String getAnimName()
Get the animName, which is the name of the animation as usable by the "animations" attribute...
abstract void finishParseArchetypePart(@Nullable R firstArch, @NotNull R archetype, @NotNull ErrorViewCollector errorViewCollector)
Called after the "end" line of a part has been read.
static final Pattern PATTERN_SLASH
The pattern that matches a single slash ("/").