gdx-studio

#libgdx#java#desktop

git clone https://git.pyrossh.dev/gdx-studio

An IDE for creating Games using libgdx and Java supported on all platforms Android, iOS, Desktop


src_libs/com/badlogic/gdx/tools/FileProcessor.java
a62d533 1
/*******************************************************************************
a62d533 2
 * Copyright 2011 See AUTHORS file.
a62d533 3
 * 
a62d533 4
 * Licensed under the Apache License, Version 2.0 (the "License");
a62d533 5
 * you may not use this file except in compliance with the License.
a62d533 6
 * You may obtain a copy of the License at
a62d533 7
 * 
a62d533 8
 *   http://www.apache.org/licenses/LICENSE-2.0
a62d533 9
 * 
a62d533 10
 * Unless required by applicable law or agreed to in writing, software
a62d533 11
 * distributed under the License is distributed on an "AS IS" BASIS,
a62d533 12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
a62d533 13
 * See the License for the specific language governing permissions and
a62d533 14
 * limitations under the License.
a62d533 15
 ******************************************************************************/
a62d533 16
a62d533 17
package com.badlogic.gdx.tools;
a62d533 18
a62d533 19
import com.badlogic.gdx.utils.Array;
a62d533 20
a62d533 21
import java.io.File;
a62d533 22
import java.io.FilenameFilter;
a62d533 23
import java.util.ArrayList;
a62d533 24
import java.util.Collections;
a62d533 25
import java.util.Comparator;
a62d533 26
import java.util.LinkedHashMap;
a62d533 27
import java.util.regex.Pattern;
a62d533 28
a62d533 29
/** Collects files recursively, filtering by file name. Callbacks are provided to process files and the results are collected,
a62d533 30
 * either {@link #processFile(Entry)} or {@link #processDir(Entry, ArrayList)} can be overridden, or both. The entries provided to
a62d533 31
 * the callbacks have the original file, the output directory, and the output file. If {@link #setFlattenOutput(boolean)} is
a62d533 32
 * false, the output will match the directory structure of the input.
a62d533 33
 * @author Nathan Sweet */
a62d533 34
public class FileProcessor {
a62d533 35
	FilenameFilter inputFilter;
a62d533 36
	Comparator<File> comparator = new Comparator<File>() {
a62d533 37
		public int compare (File o1, File o2) {
a62d533 38
			return o1.getName().compareTo(o2.getName());
a62d533 39
		}
a62d533 40
	};
a62d533 41
	Array<Pattern> inputRegex = new Array();
a62d533 42
	String outputSuffix;
a62d533 43
	ArrayList<Entry> outputFiles = new ArrayList();
a62d533 44
	boolean recursive = true;
a62d533 45
	boolean flattenOutput;
a62d533 46
a62d533 47
	Comparator<Entry> entryComparator = new Comparator<Entry>() {
a62d533 48
		public int compare (Entry o1, Entry o2) {
a62d533 49
			return comparator.compare(o1.inputFile, o2.inputFile);
a62d533 50
		}
a62d533 51
	};
a62d533 52
a62d533 53
	public FileProcessor () {
a62d533 54
	}
a62d533 55
a62d533 56
	/** Copy constructor. */
a62d533 57
	public FileProcessor (FileProcessor processor) {
a62d533 58
		inputFilter = processor.inputFilter;
a62d533 59
		comparator = processor.comparator;
a62d533 60
		inputRegex.addAll(processor.inputRegex);
a62d533 61
		outputSuffix = processor.outputSuffix;
a62d533 62
		recursive = processor.recursive;
a62d533 63
		flattenOutput = processor.flattenOutput;
a62d533 64
	}
a62d533 65
a62d533 66
	public FileProcessor setInputFilter (FilenameFilter inputFilter) {
a62d533 67
		this.inputFilter = inputFilter;
a62d533 68
		return this;
a62d533 69
	}
a62d533 70
a62d533 71
	/** Sets the comparator for {@link #processDir(Entry, ArrayList)}. By default the files are sorted by alpha. */
a62d533 72
	public FileProcessor setComparator (Comparator<File> comparator) {
a62d533 73
		this.comparator = comparator;
a62d533 74
		return this;
a62d533 75
	}
a62d533 76
a62d533 77
	public FileProcessor addInputSuffix (String... suffixes) {
a62d533 78
		for (String suffix : suffixes)
a62d533 79
			addInputRegex(".*" + Pattern.quote(suffix));
a62d533 80
		return this;
a62d533 81
	}
a62d533 82
a62d533 83
	public FileProcessor addInputRegex (String... regexes) {
a62d533 84
		for (String regex : regexes)
a62d533 85
			inputRegex.add(Pattern.compile(regex));
a62d533 86
		return this;
a62d533 87
	}
a62d533 88
a62d533 89
	/** Sets the suffix for output files, replacing the extension of the input file. */
a62d533 90
	public FileProcessor setOutputSuffix (String outputSuffix) {
a62d533 91
		this.outputSuffix = outputSuffix;
a62d533 92
		return this;
a62d533 93
	}
a62d533 94
a62d533 95
	public FileProcessor setFlattenOutput (boolean flattenOutput) {
a62d533 96
		this.flattenOutput = flattenOutput;
a62d533 97
		return this;
a62d533 98
	}
a62d533 99
a62d533 100
	/** Default is true. */
a62d533 101
	public FileProcessor setRecursive (boolean recursive) {
a62d533 102
		this.recursive = recursive;
a62d533 103
		return this;
a62d533 104
	}
a62d533 105
a62d533 106
	/** @param outputRoot May be null.
a62d533 107
	 * @see #process(File, File) */
a62d533 108
	public ArrayList<Entry> process (String inputFile, String outputRoot) throws Exception {
a62d533 109
		return process(new File(inputFile), outputRoot == null ? null : new File(outputRoot));
a62d533 110
	}
a62d533 111
a62d533 112
	/** Processes the specified input file or directory.
a62d533 113
	 * @param outputRoot May be null if there is no output from processing the files.
a62d533 114
	 * @return the processed files added with {@link #addProcessedFile(Entry)}. */
a62d533 115
	public ArrayList<Entry> process (File inputFile, File outputRoot) throws Exception {
a62d533 116
		if (!inputFile.exists()) throw new IllegalArgumentException("Input file does not exist: " + inputFile.getAbsolutePath());
a62d533 117
		if (inputFile.isFile())
a62d533 118
			return process(new File[] {inputFile}, outputRoot);
a62d533 119
		else
a62d533 120
			return process(inputFile.listFiles(), outputRoot);
a62d533 121
	}
a62d533 122
a62d533 123
	/** Processes the specified input files.
a62d533 124
	 * @param outputRoot May be null if there is no output from processing the files.
a62d533 125
	 * @return the processed files added with {@link #addProcessedFile(Entry)}. */
a62d533 126
	public ArrayList<Entry> process (File[] files, File outputRoot) throws Exception {
a62d533 127
		if (outputRoot == null) outputRoot = new File("");
a62d533 128
		outputFiles.clear();
a62d533 129
a62d533 130
		LinkedHashMap<File, ArrayList<Entry>> dirToEntries = new LinkedHashMap();
a62d533 131
		process(files, outputRoot, outputRoot, dirToEntries, 0);
a62d533 132
a62d533 133
		ArrayList<Entry> allEntries = new ArrayList();
a62d533 134
		for (java.util.Map.Entry<File, ArrayList<Entry>> mapEntry : dirToEntries.entrySet()) {
a62d533 135
			ArrayList<Entry> dirEntries = mapEntry.getValue();
a62d533 136
			if (comparator != null) Collections.sort(dirEntries, entryComparator);
a62d533 137
a62d533 138
			File inputDir = mapEntry.getKey();
a62d533 139
			File newOutputDir = null;
a62d533 140
			if (flattenOutput)
a62d533 141
				newOutputDir = outputRoot;
a62d533 142
			else if (!dirEntries.isEmpty()) //
a62d533 143
				newOutputDir = dirEntries.get(0).outputDir;
a62d533 144
			String outputName = inputDir.getName();
a62d533 145
			if (outputSuffix != null) outputName = outputName.replaceAll("(.*)\\..*", "$1") + outputSuffix;
a62d533 146
a62d533 147
			Entry entry = new Entry();
a62d533 148
			entry.inputFile = mapEntry.getKey();
a62d533 149
			entry.outputDir = newOutputDir;
a62d533 150
			if (newOutputDir != null)
a62d533 151
				entry.outputFile = newOutputDir.length() == 0 ? new File(outputName) : new File(newOutputDir, outputName);
a62d533 152
a62d533 153
			try {
a62d533 154
				processDir(entry, dirEntries);
a62d533 155
			} catch (Exception ex) {
a62d533 156
				throw new Exception("Error processing directory: " + entry.inputFile.getAbsolutePath(), ex);
a62d533 157
			}
a62d533 158
			allEntries.addAll(dirEntries);
a62d533 159
		}
a62d533 160
a62d533 161
		if (comparator != null) Collections.sort(allEntries, entryComparator);
a62d533 162
		for (Entry entry : allEntries) {
a62d533 163
			try {
a62d533 164
				processFile(entry);
a62d533 165
			} catch (Exception ex) {
a62d533 166
				throw new Exception("Error processing file: " + entry.inputFile.getAbsolutePath(), ex);
a62d533 167
			}
a62d533 168
		}
a62d533 169
a62d533 170
		return outputFiles;
a62d533 171
	}
a62d533 172
a62d533 173
	private void process (File[] files, File outputRoot, File outputDir, LinkedHashMap<File, ArrayList<Entry>> dirToEntries,
a62d533 174
		int depth) {
a62d533 175
		// Store empty entries for every directory.
a62d533 176
		for (File file : files) {
a62d533 177
			File dir = file.getParentFile();
a62d533 178
			ArrayList<Entry> entries = dirToEntries.get(dir);
a62d533 179
			if (entries == null) {
a62d533 180
				entries = new ArrayList();
a62d533 181
				dirToEntries.put(dir, entries);
a62d533 182
			}
a62d533 183
		}
a62d533 184
a62d533 185
		for (File file : files) {
a62d533 186
			if (file.isFile()) {
a62d533 187
				if (inputRegex.size > 0) {
a62d533 188
					boolean found = false;
a62d533 189
					for (Pattern pattern : inputRegex) {
a62d533 190
						if (pattern.matcher(file.getName()).matches()) {
a62d533 191
							found = true;
a62d533 192
							continue;
a62d533 193
						}
a62d533 194
					}
a62d533 195
					if (!found) continue;
a62d533 196
				}
a62d533 197
a62d533 198
				File dir = file.getParentFile();
a62d533 199
				if (inputFilter != null && !inputFilter.accept(dir, file.getName())) continue;
a62d533 200
a62d533 201
				String outputName = file.getName();
a62d533 202
				if (outputSuffix != null) outputName = outputName.replaceAll("(.*)\\..*", "$1") + outputSuffix;
a62d533 203
a62d533 204
				Entry entry = new Entry();
a62d533 205
				entry.depth = depth;
a62d533 206
				entry.inputFile = file;
a62d533 207
				entry.outputDir = outputDir;
a62d533 208
a62d533 209
				if (flattenOutput) {
a62d533 210
					entry.outputFile = new File(outputRoot, outputName);
a62d533 211
				} else {
a62d533 212
					entry.outputFile = new File(outputDir, outputName);
a62d533 213
				}
a62d533 214
a62d533 215
				dirToEntries.get(dir).add(entry);
a62d533 216
			}
a62d533 217
			if (recursive && file.isDirectory()) {
a62d533 218
				File subdir = outputDir.getPath().length() == 0 ? new File(file.getName()) : new File(outputDir, file.getName());
a62d533 219
				process(file.listFiles(inputFilter), outputRoot, subdir, dirToEntries, depth + 1);
a62d533 220
			}
a62d533 221
		}
a62d533 222
	}
a62d533 223
a62d533 224
	/** Called with each input file. */
a62d533 225
	protected void processFile (Entry entry) throws Exception {
a62d533 226
	}
a62d533 227
a62d533 228
	/** Called for each input directory. The files will be {@link #setComparator(Comparator) sorted}. */
a62d533 229
	protected void processDir (Entry entryDir, ArrayList<Entry> files) throws Exception {
a62d533 230
	}
a62d533 231
a62d533 232
	/** This method should be called by {@link #processFile(Entry)} or {@link #processDir(Entry, ArrayList)} if the return value of
a62d533 233
	 * {@link #process(File, File)} or {@link #process(File[], File)} should return all the processed files. */
a62d533 234
	protected void addProcessedFile (Entry entry) {
a62d533 235
		outputFiles.add(entry);
a62d533 236
	}
a62d533 237
a62d533 238
	/** @author Nathan Sweet */
a62d533 239
	static public class Entry {
a62d533 240
		public File inputFile;
a62d533 241
		/** May be null. */
a62d533 242
		public File outputDir;
a62d533 243
		public File outputFile;
a62d533 244
		public int depth;
a62d533 245
a62d533 246
		public Entry () {
a62d533 247
		}
a62d533 248
a62d533 249
		public Entry (File inputFile, File outputFile) {
a62d533 250
			this.inputFile = inputFile;
a62d533 251
			this.outputFile = outputFile;
a62d533 252
		}
a62d533 253
a62d533 254
		public String toString () {
a62d533 255
			return inputFile.toString();
a62d533 256
		}
a62d533 257
	}
a62d533 258
}