Source code: com/flexstor/common/util/UrlAnalyzer.java
1 /*
2 * UrlAnalyzer.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:31 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.common.util;
12
13 import java.net.UnknownHostException;
14
15 /**
16 * This class offers several methods to return the different parts of a file path.
17 * These parts are:
18 * - Remote file protocol
19 * - Server name; in DNS form or name-only form
20 * - location (not including file name)
21 * - file name
22 * - separator character
23 * It also returns whether path is local or remote
24 */
25 public abstract class UrlAnalyzer
26 {
27 public static final char UNIX_SEPARATOR = '/';
28 public static final char WINDOWS_SEPARATOR = '\\';
29 public static final char MAC_SEPARATOR = ':';
30
31 /**
32 * Returns the remote file protocol for the path specified. If the path is local, it will return
33 * null.
34 */
35 public static String getRemoteFileProtocol( String sPath )
36 {
37 int nIdx;
38 if ( (nIdx = sPath.indexOf( "://" )) != -1 )
39 return sPath.substring( 0, nIdx );
40 else
41 return null;
42 }
43
44 /**
45 * Returns DNS name of the server if the path represents a remote url. If it represents a local
46 * path, it will return the DNS for the local server.
47 */
48 public static String getServerDNS( String sPath )
49 {
50 int nIdx;
51 if ( (nIdx = sPath.indexOf( "://" )) != -1 )
52 return sPath.substring( nIdx + 3, sPath.indexOf("/", nIdx + 4) );
53 else
54 {
55 // If this code is running under the FlexDBServer, use FlexDbServerHost for returning
56 // the server name
57 if ( FlexDbServerHost.isInitialized() )
58 return ServerList.getDNSName( FlexDbServerHost.getLocalHostName() );
59 else
60 return ServerList.getDNSName( InetUtil.getLocalHostName() );
61 }
62 }
63
64 /**
65 * Returns the name of the server (not full DNS) if the path represents a remote url. If it represents
66 * a local path, it will return the name of the local server.
67 */
68 public static String getServerName( String sPath )
69 {
70 String sDNS = getServerDNS( sPath );
71 return ServerList.getServerName( sDNS );
72 }
73
74 /**
75 * Returns true if the path is local, false if remote.
76 */
77 public static boolean isPathLocal( String sPath )
78 {
79 try
80 {
81 String sDNS = getServerDNS( sPath );
82 // If this code is running under the FlexDBServer, use FlexDbServerHost
83 if ( FlexDbServerHost.isInitialized() )
84 return FlexDbServerHost.isLocalHost( sDNS );
85 else
86 return InetUtil.isLocalHost( sDNS );
87 }
88 catch ( UnknownHostException uhe )
89 {
90 return false;
91 }
92 }
93
94 /**
95 * Returns the path String of this path's parent, or an empty String if this path does not name
96 * a parent directory.
97 * The parent of a path consists of each name in the path's name sequence except for the last. If
98 * the name sequence is empty then the path does not name a parent directory.
99 * The parent of a path does not contain the protocol neither the server name.
100 * The parent of a path does not end in a file separator character.
101 */
102 public static String getLocalParent( String sPath )
103 {
104 char sSeparator = getSeparatorChar(sPath);
105 String sProtocol = getRemoteFileProtocol(sPath);
106 int nStart;
107 if ( sProtocol != null )
108 nStart = sPath.indexOf( sSeparator, (sPath.indexOf("://") + 3) ); // first separator char after "protocol://"
109 else
110 nStart = sPath.indexOf( sSeparator );
111
112 int nEnd = sPath.lastIndexOf(sSeparator); // last separator character
113 return sPath.substring( nStart, nEnd );
114 }
115
116 /**
117 * Returns the file name.
118 * The file name is the last name in the path. A file name does not imply that it is a file or a
119 * directory.
120 * To find out whether it is a directory or a file use FlexXFile.isFile() and FlexXFile.isDirectory().
121 */
122 public static String getFileName( String sPath )
123 {
124 char sSeparator = getSeparatorChar(sPath);
125 return sPath.substring( sPath.lastIndexOf(sSeparator) + 1 );
126 }
127
128 /**
129 * Returns the local path to the file specified; not including the protocol neither the server name.
130 */
131 public static String getLocalPath( String sPath )
132 {
133 char sSeparator = getSeparatorChar(sPath);
134 String sProtocol = getRemoteFileProtocol(sPath);
135 int nStart;
136 if ( sProtocol != null )
137 nStart = sPath.indexOf( sSeparator, (sPath.indexOf("://") + 3) ); // first separator char after "protocol://"
138 else
139 nStart = sPath.indexOf( sSeparator );
140
141 return sPath.substring( nStart );
142 }
143
144 /**
145 * Returns the file separator character as used in the path
146 */
147 public static char getSeparatorChar( String sPath )
148 {
149 if ( sPath.indexOf( "://" ) != -1 )
150 return UNIX_SEPARATOR;
151 else if ( sPath.indexOf( UNIX_SEPARATOR ) != -1 )
152 return UNIX_SEPARATOR;
153 else if ( sPath.indexOf( WINDOWS_SEPARATOR ) != -1 )
154 return WINDOWS_SEPARATOR;
155 else if ( sPath.indexOf( MAC_SEPARATOR ) != -1 )
156 return MAC_SEPARATOR;
157 else
158 return System.getProperty("file.separator").charAt(0);
159 }
160
161 /**
162 * This method takes two paths, decomposes them into server, location, file name and examines
163 * each piece to determine if both paths represent the same location.
164 * If a path does not contain a protocol, it assumes it is a local path.
165 * If a path does not contain a server, it assumes it is a local path.
166 * Path will be equal, if their server, location and file name matches, regardless of the
167 * protocol specified.
168 * Example: 1) nfs://server.com/path/to/file is equal to ftp://server.com/path/to/file
169 * 2) flex://server.com/path/to/file is equal to /path/to/file
170 *
171 * @param sPath1 The first path to analyze
172 * @param bIsFile1 True if sPath1 represents a file, false if it represents a directory
173 * @param sPath2 The second path to analyze
174 * @param bIsFile2 True if sPath2 represents a file, false if it represents a directory
175 * @param bIgnoreName Ignores the file names and only compares the directories, set this value to
176 * true if one or both paths represent directories
177 * @return true if both paths represent the same location, false otherwise
178 */
179 public static boolean comparePaths( String sPath1, boolean bIsFile1, String sPath2, boolean bIsFile2, boolean bIgnoreName )
180 {
181 // Get the server for both files and compare them
182 String sServer1 = getServerDNS(sPath1);
183 String sServer2 = getServerDNS(sPath2);
184
185 if ( !sServer1.equals(sServer2) )
186 {
187 // Since there could be two FlexDBServers running in the same machine, both using different
188 // server names, lets use FlexDbServerHost to determine that they are the same or not
189 if ( !FlexDbServerHost.isInitialized() )
190 return false;
191
192 if ( !(FlexDbServerHost.isLocalHost(sServer1) && FlexDbServerHost.isLocalHost(sServer2)) )
193 return false;
194 }
195
196 // Servers are equal, now test the locations
197 String sLocation1;
198 if ( bIsFile1 )
199 sLocation1 = getLocalParent(sPath1);
200 else
201 sLocation1 = getLocalPath(sPath1);
202
203 String sLocation2;
204 if ( bIsFile2 )
205 sLocation2 = getLocalParent(sPath2);
206 else
207 sLocation2 = getLocalPath(sPath2);
208
209 // Make sure paths contain leading and trailing slashes
210 String sSeparator = String.valueOf( UrlAnalyzer.getSeparatorChar(sLocation1) );
211 if ( !sLocation1.startsWith(sSeparator) )
212 sLocation1 = sSeparator + sLocation1;
213 if ( !sLocation1.endsWith(sSeparator) )
214 sLocation1 = sLocation1 + sSeparator;
215
216 if ( !sLocation2.startsWith(sSeparator) )
217 sLocation2 = sSeparator + sLocation2;
218 if ( !sLocation2.endsWith(sSeparator) )
219 sLocation2 = sLocation2 + sSeparator;
220
221 if ( !sLocation1.equals(sLocation2) )
222 return false;
223
224 // Location are equals, now test file names
225 // Get the file name for both files
226 if ( !bIgnoreName )
227 {
228 String sFile1 = "", sFile2 = "";
229 if ( bIsFile1 )
230 sFile1 = getFileName(sPath1);
231 if ( bIsFile2 )
232 sFile2 = getFileName(sPath2);
233
234 if ( !sFile1.equals(sFile2) )
235 return false;
236 }
237
238 // everything was successful
239 return true;
240 }
241 }