1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 import java.io.*;
23 import java.util.Vector;
24 
25 
26 public class SubscribedNewsgroups {
27 
28 
29 	private static NewsGroup[] allSubscribed = null;
30 	private static boolean windows = false;
31 
main( String[] args )32 	public static void main( String[] args ) {
33 		// Test the class
34 		SubscribedNewsgroups subscribed = new SubscribedNewsgroups();
35 
36 		NewsGroup allGroups[] = subscribed.getNewsGroups();
37 
38 		if( allGroups == null )
39 		{
40 			System.out.println("Could not find subscribed newsgroups from mozilla/netscape mailrc files");
41 		}
42 		else
43 		{
44 			for( int i=0; i < allGroups.length; i++ )
45 			{
46 				System.out.println( "Hostname is: " + allGroups[i].getHostName() + " Newsgroup is: " + allGroups[i].getNewsgroupName() );
47 			}
48 		}
49 	}
50 
51 
52 
53 	// Only public method of the class
54 	// Returns and array of unique NewsGroup objects
getNewsGroups()55 	public NewsGroup[] getNewsGroups()
56 	{
57 		windows = false;
58 		if( System.getProperty( "os.name" ).indexOf( "Windows" ) != -1 )
59 		{
60 			windows = true;
61 		}
62 
63 		String mozillaHome = "";
64 		if( windows )
65 		{
66 			mozillaHome = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + "Application Data" + System.getProperty( "file.separator" ) + "Mozilla" + System.getProperty( "file.separator" ) + "Profiles";
67 			//System.out.println( "Windows mozilla path: " + mozillaHome );
68 		}
69 		else
70 		{
71 			mozillaHome = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".mozilla";
72 			//System.out.println( "Unix/Linux mozilla path: " + mozillaHome );
73 		}
74 		if( !new File( mozillaHome ).isDirectory() )
75 		{
76 			//System.out.println("Could not find .mozilla directory");
77 			return null;
78 		}
79 		//System.out.println(".mozilla directory found");
80 
81 		// Get all the profiles belonging to the user
82 		File profiles[] = findProfiles( new File ( mozillaHome ) );
83 		if( profiles.length < 1 )
84 		{
85 			//System.out.println("Could not find Profiles");
86 			return null;
87 		}
88 		//System.out.println("Profiles found");
89 
90 		// Get the News directory for each profile
91 		File allNewsDirs[] = new File[ profiles.length ];
92 		for( int i=0; i < profiles.length; i++ ) {
93 			File newsDir = findNewsDir( profiles[i] );
94 			allNewsDirs[i] = newsDir;
95 			//System.out.println( "News is at: " + newsDir.getPath() );
96 		}
97 		// Check that at least one News directory exists and remove nulls
98 		boolean newsFound = false;
99 		//Vector nonNullNews = new Vector();
100 		for( int i=0; i < allNewsDirs.length; i++ ) {
101 			if( allNewsDirs[i] != null ) {
102 				newsFound = true;
103 				break;
104 			}
105 		}
106 		if( !newsFound )
107 		{
108 			//System.out.println("Could not find News directory");
109 			return null;
110 		}
111 		//System.out.println("News directory found");
112 
113 		// Get all the mailrc files for each News directory
114 		File allMailrcs[] = findMailrcFiles( allNewsDirs );
115 		if( allMailrcs == null )
116 		{
117 			//System.out.println("Could not find mailrc files");
118 			return null;
119 		}
120 		//System.out.println("mailrc files found");
121 
122 		Vector subscribed = new Vector();
123 		// Get the newsgroups in each mailrc file
124 		for( int i=0; i < allMailrcs.length; i++ )
125 		{
126 			File mailrc = (File) allMailrcs[i];
127 			NewsGroup newsgroup[] = findNewsgroups( mailrc );
128 			//if the Newsgroup has not already been added to the list
129 			for( int j=0; j < newsgroup.length; j++ )
130 			{
131 				// if newsgroup is unique then add to the list
132 				if( !listed( newsgroup[j], subscribed ) )
133 				{
134 					subscribed.addElement( newsgroup[j] );
135 				}
136 			}
137 		}
138 
139 		// Copy all unique Newsgroups into the global array
140 		allSubscribed = new NewsGroup[ subscribed.size() ];
141 		subscribed.copyInto( allSubscribed );
142 		// Test that at least one subscribed newsgroup has been found
143 		if( allSubscribed.length < 1 )
144 		{
145 			//System.out.println("Could not find Subscribed newsgroups ");
146 			return null;
147 		}
148 		//System.out.println("Subscribed newsgroups found");
149 
150 		return allSubscribed;
151 	}
152 
153 
154 
155 
156 	// Tests if the NewsGroup object has already been listed by another mailrc file
listed( NewsGroup newsgroup, Vector uniqueSubscription )157 	private static boolean listed( NewsGroup newsgroup, Vector uniqueSubscription )
158 	{
159 		for(int i=0; i < uniqueSubscription.size(); i++)
160 		{
161 			NewsGroup tempGroup = (NewsGroup) uniqueSubscription.elementAt(i);
162 			// Test for duplication
163 			if(newsgroup.getHostName().equalsIgnoreCase( tempGroup.getHostName()) &&
164 			   newsgroup.getNewsgroupName().equalsIgnoreCase( tempGroup.getNewsgroupName() ) )
165 				return true;
166 		}
167 		return false;
168 	}
169 
170 
171 
172 
173 	// Finds all the NewsGroups in an individual mailrc file
findNewsgroups(File mailrcfile )174 	private static NewsGroup[] findNewsgroups(File mailrcfile )
175 	{
176 
177 		String hostname = "";
178 		String newsgroup = "";
179 		NewsGroup mailrcNewsGroups[] = null;
180 
181 		//Retrieve name of news host/server from file name
182 		//Sequentially access each of the newsgroups
183 		//If the newsgroup is not already contained in the global NewsGroup[] array then add it
184 
185 		String filename = mailrcfile.getPath();
186 		if( windows )
187 		{
188 			// Windows format "staroffice-news.germany.sun.com.rc"
189 			int hostNameStart = filename.lastIndexOf("\\") + 1;
190 			int hostNameEnd = filename.indexOf(".rc");
191 			hostname = filename.substring( hostNameStart, hostNameEnd );
192 		}
193 		else
194 		{
195 			// Unix/Linux format "newsrc-staroffice-news.germany.sun.com"
196 			int hostNameStart = filename.lastIndexOf("newsrc-") + 7;
197 			hostname = filename.substring( hostNameStart, filename.length() );
198 		}
199 
200 		// Assumes the content format in Window is the same as Unix/Linux (unknown at the moment)
201 		// i.e. a list of newsgroups each ending with a ":"
202 		LineNumberReader in = null;
203 		try {
204 			in = new LineNumberReader( new FileReader( mailrcfile ) );
205 			Vector groups = new Vector();
206 			String inString = "";
207 			int line = 0;
208 			while( inString != null )
209 			{
210 				in.setLineNumber( line );
211 				inString = in.readLine();
212 				line++;
213 				if( inString != null )
214 				{
215 					int newsgroupEnd = inString.indexOf(":");
216 					newsgroup = inString.substring( 0, newsgroupEnd );
217 					NewsGroup group = new NewsGroup( hostname, newsgroup );
218 					groups.addElement( group );
219 				}
220 			}
221 			mailrcNewsGroups = new NewsGroup[ groups.size() ];
222 			groups.copyInto(mailrcNewsGroups);
223 			in.close();
224 		}
225 		catch( IOException ioe ) {
226 			ioe.printStackTrace();
227 		}
228 
229 		return mailrcNewsGroups;
230 	}
231 
232 
233 	// Finds all the mailrc files for all the given News directories
findMailrcFiles(File[] newsDirs)234 	private static File[] findMailrcFiles(File[] newsDirs)
235 	{
236 		Vector allFiles = new Vector();
237 
238 		for( int i=0; i < newsDirs.length; i++ )
239 		{
240 			//System.out.println( "Finding mailrc for: " + newsDirs[i] );
241 			if( newsDirs[i] != null )
242 			{
243 				File mailrcFiles[] = newsDirs[i].listFiles( new VersionFilter() );
244 				if( mailrcFiles != null )
245 				{
246 					//System.out.println( "Number found: " + mailrcFiles.length );
247 					for( int j=0; j < mailrcFiles.length; j++ )
248 					{
249 						//System.out.println( "This mailrc was found: " + mailrcFiles[j] );
250 						allFiles.addElement( mailrcFiles[j] );
251 					}
252 				}
253 			}
254 		}
255 		File allMailrcFiles[] = new File[ allFiles.size() ];
256 		allFiles.copyInto(allMailrcFiles);
257 
258 		//System.out.println( "number of mailrcs in total: " + allMailrcFiles.length );
259 
260 		if( allMailrcFiles.length == 0 ) {
261 			//System.out.println( "Returning null");
262 			return null;
263 		}
264 
265 		//System.out.println( "Returning an File array containing mailrcs");
266 		return allMailrcFiles;
267 	}
268 
269 
270 	// Finds all profiles belonging to one user (can be more than one)
findProfiles(File start)271 	private static File[] findProfiles(File start)
272 	{
273 		// Get all files and directories in .mozilla
274 		File allFiles[] = start.listFiles();
275 		File[] dirs = new File[allFiles.length];
276 		int dirCounter = 0;
277 
278 		// Remove files leaving directories only
279 		for(int i=0; i < allFiles.length; i++ )
280 		{
281 			if(allFiles[i].isDirectory())
282 			{
283 				dirs[dirCounter] = allFiles[i];
284 				dirCounter++;
285 			}
286 		}
287 
288 		// Add each directory to a user profile array
289 		File[] profileDirs = new File[dirCounter];
290 		for( int i=0; i < dirCounter; i++ )
291 		{
292 			profileDirs[i] = dirs[i];
293 		}
294 
295 		// return a File array containing the profile dirs
296 		return profileDirs;
297 	}
298 
299 
300 	// Recursively searches for the News directory for a given profile directory
findNewsDir(File start)301         private static File findNewsDir(File start)
302         {
303                 File mailrcFile = null;
304 
305 		// File array containing all matches for the version filter ("News")
306                 File files[] = start.listFiles(new VersionFilter());
307 		// If the array is empty then no matches were found
308                 if (files.length == 0)
309                 {
310 			// File array of all the directories in File start
311                         File dirs[] = start.listFiles(new DirFilter());
312 			// for each of the directories check for a match
313                         for (int i=0; i< dirs.length; i++)
314                         {
315                                 mailrcFile = findNewsDir(dirs[i]);
316                                 if (mailrcFile != null)
317                                 {
318 					// break the for loop
319                                         break;
320                                 }
321                         }
322                 }
323                 else
324 		{
325 			// end recursion
326 			// Check for a News directory inside the News directory (fix for bug)
327 			// Original solution had only "mailrcFile = files[0];"
328 
329 			boolean noChildNews = true;
330 			File checkChildNewsDirs[] = files[0].listFiles(new VersionFilter());
331 			if( checkChildNewsDirs != null )
332 			{
333 				for( int i=0; i < checkChildNewsDirs.length; i++ )
334 				{
335 					if( checkChildNewsDirs[i].getName().equals( "News" ) )
336 					{
337 						noChildNews = false;
338 						break;
339 					}
340 				}
341 			}
342 
343 			if( noChildNews )
344 			{
345        				mailrcFile = files[0];
346 			}
347 			else
348 			{
349 				String childNewsPathName = files[0].getAbsolutePath() + System.getProperty( "file.separator" ) + "News";
350 				mailrcFile = new File( childNewsPathName );
351 			}
352 
353 		}
354 
355 		// return a File representing the News dir in a profile
356                 return mailrcFile;
357 	}
358 }
359 
360 
361 
362 class DirFilter implements FileFilter
363 {
accept(File aFile)364         public boolean accept(File aFile)
365         {
366                 return aFile.isDirectory();
367         }
368 }
369 
370 
371 class VersionFilter implements FileFilter
372 {
accept(File aFile)373         public boolean accept(File aFile)
374         {
375 		if( System.getProperty( "os.name" ).indexOf( "Windows" ) != -1 )
376 		{
377 			if (aFile.getName().compareToIgnoreCase("News") == 0 ||
378 			aFile.getName().indexOf(".rc") != -1 )
379 			{
380 				return true;
381 			}
382 		}
383 		else
384 		{
385 			if (aFile.getName().compareToIgnoreCase("News") == 0 ||
386 			aFile.getName().indexOf("newsrc") != -1 )
387 			{
388 				return true;
389 			}
390 		}
391 
392                 return false;
393         }
394 }
395