Gridarta Editor
AbstractFilesResourcesReader.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.resource;
21 
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.io.InputStreamReader;
27 import java.io.Reader;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.List;
47 import net.sf.gridarta.utils.Pair;
48 import org.apache.log4j.Category;
49 import org.apache.log4j.Logger;
50 import org.jetbrains.annotations.NotNull;
51 import org.jetbrains.annotations.Nullable;
52 
58 public abstract class AbstractFilesResourcesReader<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends AbstractResourcesReader<G> {
59 
63  private static final Category LOG = Logger.getLogger(AbstractFilesResourcesReader.class);
64 
68  @NotNull
69  private final File archDirectory;
70 
74  @NotNull
76 
80  @NotNull
82 
86  @NotNull
88 
92  @NotNull
94 
106  protected AbstractFilesResourcesReader(@NotNull final File archDirectory, @NotNull final ArchetypeSet<G, A, R> archetypeSet, @NotNull final AbstractArchetypeParser<G, A, R, ?> archetypeParser, @NotNull final ArchFaceProvider archFaceProvider, @NotNull final File collectedDirectory, @Nullable final String imageSet, @NotNull final AnimationObjects animationObjects, @NotNull final FaceObjects faceObjects) {
107  super(collectedDirectory, imageSet, animationObjects, faceObjects);
108  this.archDirectory = archDirectory;
109  this.archetypeSet = archetypeSet;
110  this.archetypeParser = archetypeParser;
111  this.archFaceProvider = archFaceProvider;
112  this.animationObjects = animationObjects;
113  }
114 
115  @NotNull
116  @Override
117  public FaceProvider read(@NotNull final ErrorView errorView, @NotNull final List<G> invObjects) {
118  archetypeSet.setLoadedFromArchive(false);
119  final int animationObjectsSize = animationObjects.size();
120  final int archetypeCount = archetypeSet.getArchetypeCount();
121  final Collection<Pair<String, File>> animFiles = new ArrayList<>();
122  final ErrorViewCollector archDirectoryErrorViewCollector = new ErrorViewCollector(errorView, archDirectory);
123  loadArchetypesFromFiles(archDirectoryErrorViewCollector, archetypeParser, "", archDirectory, 0, "default", "default", invObjects, archFaceProvider, errorView, animFiles);
124  loadAnimationsFromFiles(archDirectoryErrorViewCollector, animFiles);
125  if (LOG.isInfoEnabled()) {
126  LOG.info("Loaded " + (animationObjects.size() - animationObjectsSize) + " animations from '" + archDirectory + "'.");
127  }
128  if (LOG.isInfoEnabled()) {
129  LOG.info("Loaded " + (archetypeSet.getArchetypeCount() - archetypeCount) + " archetypes from '" + archDirectory + "'.");
130  }
131  if (LOG.isInfoEnabled()) {
132  LOG.info("Loaded " + archFaceProvider.size() + " faces from '" + archDirectory + "'.");
133  }
134  return archFaceProvider;
135  }
136 
152  private void loadArchetypesFromFiles(@NotNull final ErrorViewCollector errorViewCollector, @NotNull final AbstractArchetypeParser<G, A, R, ?> archetypeParser, @NotNull final String path, @NotNull final File f, final int folderLevel, @NotNull final String panelName, @NotNull final String folderName, @NotNull final List<G> invObjects, @NotNull final ArchFaceProvider archFaceProvider, @NotNull final ErrorView errorView, @NotNull final Collection<Pair<String, File>> animFiles) {
153  final String name = f.getName();
154  if (f.isDirectory()) {
155  // now, setup the archetype panels
156  if (isValidEntry(folderLevel, name)) {
157  final String[] entries = f.list();
158  if (entries != null) {
159  Arrays.sort(entries);
160  final String thisPanelName = folderLevel == 1 ? name : panelName;
161  final String thisFolderName = folderLevel == 1 || folderLevel == 2 ? name : folderName;
162  final String newPath = folderLevel == 0 ? "" : path + "/" + name;
163  for (final String entry : entries) {
164  loadArchetypesFromFiles(errorViewCollector, archetypeParser, newPath, new File(f, entry), folderLevel + 1, thisPanelName, thisFolderName, invObjects, archFaceProvider, errorView, animFiles);
165  }
166  } else {
167  errorViewCollector.addWarning(ErrorViewCategory.ARCHETYPE_DIR_INVALID, f.getPath());
168  }
169  }
170  } else if (f.isFile()) { // watch out for stuff that's not a file and not a directory!!!
171  if (FileFilters.ARC_FILE_FILTER.accept(f)) {
172  try {
173  try (FileInputStream fis = new FileInputStream(f)) {
174  try (InputStreamReader isr = new InputStreamReader(fis)) {
175  try (BufferedReader in = new BufferedReader(isr)) {
176  archetypeParser.parseArchetypeFromStream(in, null, null, null, panelName, folderName, path, invObjects, new ErrorViewCollector(errorView, f));
177  }
178  }
179  }
180  } catch (final IOException ex) {
181  new ErrorViewCollector(errorView, f).addWarning(ErrorViewCategory.ARCHETYPE_FILE_INVALID, ex.getMessage());
182  }
183  } else if (FileFilters.PNG_FILE_FILTER.accept(f)) {
184  if (archetypeSet.getImageSet() == null || name.contains("." + archetypeSet.getImageSet() + ".")) {
185  addPNGFace(f.getAbsolutePath(), path, name, errorView, archFaceProvider);
186  }
187  } else if (FileFilters.FACE_FILE_FILTER.accept(f)) {
188  parseDefFace(errorView, f.getAbsolutePath(), path);
189  } else if (FileFilters.ANIM_FILE_FILTER.accept(f)) {
190  animFiles.add(new Pair<>(path, f));
191  }
192  }
193  }
194 
201  private void parseDefFace(@NotNull final ErrorView errorView, @NotNull final String path, @NotNull final String filename) {
202  final ErrorViewCollector errorViewCollector = new ErrorViewCollector(errorView, new File(path));
203  try {
204  try (FileInputStream fis = new FileInputStream(path)) {
205  try (InputStreamReader isr = new InputStreamReader(fis)) {
206  try (Reader in = new BufferedReader(isr)) {
207  AnimationObjectsReader.loadAnimations(animationObjects, errorViewCollector, in, "animation ", true, filename, null);
208  }
209  }
210  }
211  } catch (final IOException ex) {
212  errorViewCollector.addWarning(ErrorViewCategory.FACE_FILE_INVALID, ex.getMessage());
213  } catch (final AnimationParseException ex) {
214  errorViewCollector.addWarning(ErrorViewCategory.FACE_FILE_INVALID, "line " + ex.getLineNumber() + ": parsing error: " + ex.getMessage());
215  }
216  }
217 
228  private void loadAnimationsFromFiles(@NotNull final ErrorViewCollector errorViewCollector, @NotNull final Iterable<Pair<String, File>> animFiles) {
229  for (final Pair<String, File> pair : animFiles) {
230  final String animPath = pair.getFirst();
231  final File animFile = pair.getSecond();
232  try {
233  AnimationObjectsReader.loadAnimations(animationObjects, errorViewCollector, animPath, animFile, "anim ", false);
234  } catch (final IOException ex) {
235  errorViewCollector.addWarning(ErrorViewCategory.ANIM_FILE_INVALID, ex.getMessage() + ", " + animFile);
236  } catch (final AnimationParseException ex) {
237  errorViewCollector.addWarning(ErrorViewCategory.ANIM_ENTRY_INVALID, "line " + ex.getLineNumber() + ": parsing error: " + ex.getMessage() + ", " + animFile);
238  }
239  }
240  }
241 
248  protected abstract boolean isValidEntry(int folderLevel, String name);
249 
250 }
int size()
Returns the number of faces.
void loadArchetypesFromFiles(@NotNull final ErrorViewCollector errorViewCollector, @NotNull final AbstractArchetypeParser< G, A, R, ?> archetypeParser, @NotNull final String path, @NotNull final File f, final int folderLevel, @NotNull final String panelName, @NotNull final String folderName, @NotNull final List< G > invObjects, @NotNull final ArchFaceProvider archFaceProvider, @NotNull final ErrorView errorView, @NotNull final Collection< Pair< String, File >> animFiles)
Loads all archetypes and faces by recursing through the.
This exception is thrown when parsing an animation definition file (.
Convenience class for adding messages to a ErrorView instance using a fixed category name...
Stores a pair of values.
Definition: Pair.java:26
Reading and writing of maps, handling of paths.
Utility class for reading AnimationObjects from files.
final AbstractArchetypeParser< G, A, R, ?> archetypeParser
The AbstractArchetypeParser to use.
Abstract base class for AbstractResourcesReaders that read from individual files. ...
void addWarning(@NotNull final ErrorViewCategory category)
Adds a warning message.
int size()
Get the number of objects.
Gridarta can handle frame information of animations and allow the selection of an animation using a t...
This interface represents a lazy loader that provides images on demand.
FaceProvider read(@NotNull final ErrorView errorView, @NotNull final List< G > invObjects)
final ArchFaceProvider archFaceProvider
The ArchFaceProvider to use.
void loadAnimationsFromFiles(@NotNull final ErrorViewCollector errorViewCollector, @NotNull final Iterable< Pair< String, File >> animFiles)
This method loads animations that are separately defined by looping through all files that were previ...
abstract boolean isValidEntry(int folderLevel, String name)
Returns whether a file name should be processed.
Defines possible error categories for ErrorView instances.
Interface for classes displaying error messages.
Definition: ErrorView.java:28
static void loadAnimations(@NotNull final AnimationObjects animationObjects, @NotNull final ErrorViewCollector errorViewCollector, @NotNull final String path, @NotNull final File animFile, @NotNull final String startKey, final boolean ignoreOtherText)
Loads animations from a file.
Base package of all Gridarta classes.
Utility class defining FileFilters.
void parseDefFace(@NotNull final ErrorView errorView, @NotNull final String path, @NotNull final String filename)
Loads a .face file.
static final FileFilter PNG_FILE_FILTER
Swing FileFilter for png graphics.
Reflects a game object (object on a map).
Definition: GameObject.java:36
int getArchetypeCount()
Returns the number of Archetypes available.
final AnimationObjects animationObjects
The AnimationObjects to use.
AnimationObjects is a container for AnimationObjects.
GameObjects are the objects based on Archetypes found on maps.
static final Category LOG
The logger for printing log messages.
String getImageSet()
Returns the image set.
void addPNGFace( @NotNull final String filename, @NotNull final String path, @NotNull final String name, @NotNull final ErrorView errorView, @NotNull final ArchFaceProvider archFaceProvider)
Loads a png from the file, convert it to IconImage and attach it to the face list.
AbstractFilesResourcesReader(@NotNull final File archDirectory, @NotNull final ArchetypeSet< G, A, R > archetypeSet, @NotNull final AbstractArchetypeParser< G, A, R, ?> archetypeParser, @NotNull final ArchFaceProvider archFaceProvider, @NotNull final File collectedDirectory, @Nullable final String imageSet, @NotNull final AnimationObjects animationObjects, @NotNull final FaceObjects faceObjects)
Creates a new instance.
static final FileFilter ARC_FILE_FILTER
Swing FileFilter for .arc files.
FaceObjects is a container for FaceObjects.
static final FileFilter ANIM_FILE_FILTER
Swing FileFilter for .anim files.
The face is the appearance of an object.
int getLineNumber()
Get the number of the erroneous line.
Interface that captures similarities between different ArchetypeSet implementations.
Implementation of FaceProvider which reads images from the arch directory.
Abstract base class for archetype set loader classes.
Abstract base implementation of ArchetypeParser.
void setLoadedFromArchive(boolean loadedFromArchive)
Sets whether Archetypes were loaded from an archive.
final ArchetypeSet< G, A, R > archetypeSet
The ArchetypeSet to update.
static final FileFilter FACE_FILE_FILTER
Swing FileFilter for .face files.