Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: e5d643c287bd6a77230c9a77ba4e6985a0a755e1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*******************************************************************************
 * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License 2.0 and Eclipse Distribution License
 * v1.0, both of which accompany this distribution.
 * The Eclipse Public License is available at
 * http://www.eclipse.org/org/documents/epl-2.0/.
 * The Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/
package org.eclipse.jpt.common.utility.tests.internal.eol;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
import org.eclipse.jpt.common.utility.internal.io.FileTools;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.common.utility.internal.predicate.PredicateAdapter;
import org.eclipse.jpt.common.utility.internal.transformer.TransformerAdapter;
import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.transformer.Transformer;

/**
 * List any files that have any EOLs that are not the standard
 * DOS/Windows CR-LF (<code>0x0D0A</code>).
 */
public class CheckWinEOL {

	private static final String DEFAULT_ROOT_DIR_NAME = "C:/dev/main"; //$NON-NLS-1$
	public static final int CR = 0x0D;
	public static final int LF = 0x0A;

	public static void main(String[] args) {
		main((args.length == 0) ? DEFAULT_ROOT_DIR_NAME : args[0]);
		System.exit(0);
	}

	@SuppressWarnings("nls")
	public static void main(String rootDirectoryName) {
		Iterable<File> invalidJavaFiles = getAllJavaFilesWithInvalidWinEOL(rootDirectoryName);
		int count = 0;
		System.out.println("Java files with bogus EOL:");
		for (String invalidFileName : CollectionTools.treeSet(IterableTools.transform(invalidJavaFiles, FILE_ABSOLUTE_PATH_TRANSFORMER))) {
			count++;
			System.out.print('\t');
			System.out.println(invalidFileName);
		}
		System.out.println("*** total = " + count + " ***");
	}

	/**
	 * Return all the <code>.java</code> files under the specified
	 * directory that have invalid EOL character combinations
	 * for DOS/Windows, recursing into subdirectories.
	 */
	public static Iterable<File> getAllJavaFilesWithInvalidWinEOL(String directoryName) {
		return getAllJavaFilesWithInvalidWinEOL(new File(directoryName));
	}

	/**
	 * @see #getAllJavaFilesWithInvalidWinEOL(String)
	 */
	public static Iterable<File> getAllJavaFilesWithInvalidWinEOL(File directory) {
		return extractFilesWithInvalidWinEOL(javaFiles(FileTools.getAllFiles(directory)));
	}

	/**
	 * Return all the <code>.java</code> files among the specified files.
	 */
	private static Iterable<File> javaFiles(Iterable<File> files) {
		return IterableTools.filter(files, FILE_IS_JAVA_FILE);
	}

	/**
	 * This file predicate returns whether a file is a Java file
	 * (i.e. it has a <code>.java</code> extension).
	 */
	private static final Predicate<File> FILE_IS_JAVA_FILE = new FileIsJavaFile();
	/* CU private */ static class FileIsJavaFile
		extends PredicateAdapter<File>
	{
		@Override
		public boolean evaluate(File file) {
			return file.getName().toLowerCase().endsWith(".java"); //$NON-NLS-1$
		}
	}

	/**
	 * Return all the files under the specified
	 * directory that have invalid EOL character combinations
	 * for DOS/Windows, recursing into subdirectories.
	 * <p>
	 * <strong>NB:</strong> Assume all the files are <em>text</em> files.
	 */
	public static Iterable<File> getAllFilesWithInvalidWinEOL(String directoryName) {
		return getAllFilesWithInvalidWinEOL(new File(directoryName));
	}

	/**
	 * @see #getAllFilesWithInvalidWinEOL(String)
	 */
	public static Iterable<File> getAllFilesWithInvalidWinEOL(File directory) {
		return extractFilesWithInvalidWinEOL(FileTools.getAllFiles(directory));
	}
	
	/**
	 * Extract from the specified files all the files
	 * that have invalid EOL character combinations.
	 * <p>
	 * <strong>NB:</strong> Assume all the files are <em>text</em> files.
	 */
	public static Iterable<File> extractFilesWithInvalidWinEOL(Iterable<File> files) {
		return IterableTools.filter(files, FILE_HAS_INVALID_WIN_EOL) ;
	}

	/**
	 * This file predicate returns whether a file contains any invalid
	 * EOL character combinations for DOS/Windows.
	 * Every EOL must be a CR-LF (<code>0x0D0A</code>). Any standalone
	 * CR or LF is invalid.
	 */
	private static final Predicate<File> FILE_HAS_INVALID_WIN_EOL = new FileHasInvalidWinEOL();
	/* CU private */ static class FileHasInvalidWinEOL
		extends PredicateAdapter<File>
	{
		@Override
		public boolean evaluate(File file) {
			try {
				return this.fileHasInvalidWinEOL(file);
			} catch (IOException ex) {
				ex.printStackTrace();
				return false;
			}
		}

		private boolean fileHasInvalidWinEOL(File file) throws FileNotFoundException, IOException {
			InputStream stream = new BufferedInputStream(new FileInputStream(file), 262144); // 256K
			try {
				return streamHasInvalidWinEOL(stream);
			} finally {
				stream.close();
			}
		}
	}

	/**
	 * <strong>NB:</strong> The caller of this method is responsible for
	 * closing the specified stream.
	 */
	public static boolean streamHasInvalidWinEOL(InputStream stream) throws IOException {
		// prime the characters
		int previous = -1;
		int current = stream.read();
		int next = stream.read();
		while (current != -1) {		// empty stream is OK
			if (charsAreInvalidWinEOL(previous, current, next)) {
				return true;
			}
			previous = current;
			current = next;
			next = stream.read();
		}
		return false;
	}

	public static boolean charsAreInvalidWinEOL(int previous, int current, int next) {
		if (current == CR) {
			return next != LF;
		}
		if (current == LF) {
			return previous != CR;
		}
		return false;
	}

	private static final Transformer<File, String> FILE_ABSOLUTE_PATH_TRANSFORMER = new FileAbsolutePathTransformer();
	/* CU private */ static class FileAbsolutePathTransformer
		extends TransformerAdapter<File, String>
	{
		@Override
		public String transform(File file) {
			return file.getAbsolutePath();
		}
	}
}

Back to the top