@@ -68,7 +68,7 @@ public sealed class Version {
68
68
/// iText is a registered trademark by iText Group NV.
69
69
/// Please don't change this constant.
70
70
/// </remarks>
71
- private static String iText = "iText\u00ae " ;
71
+ private static String iTextProductName = "iText\u00ae " ;
72
72
73
73
/// <summary>This String contains the version number of this iText release.</summary>
74
74
/// <remarks>
@@ -84,7 +84,7 @@ public sealed class Version {
84
84
/// iText Group requests that you retain the iText producer line
85
85
/// in every PDF that is created or manipulated using iText.
86
86
/// </remarks>
87
- private String iTextVersion = iText + " " + release + " \u00a9 2000-2017 iText Group NV" ;
87
+ private String producerLine = iTextProductName + " " + release + " \u00a9 2000-2017 iText Group NV" ;
88
88
89
89
/// <summary>The license key.</summary>
90
90
private String key = null ;
@@ -102,14 +102,9 @@ public static iText.Kernel.Version GetInstance() {
102
102
version = new iText . Kernel . Version ( ) ;
103
103
lock ( version ) {
104
104
try {
105
- String licenseeInfoMethodName = "GetLicenseeInfoForVersion" ;
106
- Type klass = GetLicenseKeyClass ( ) ;
107
- if ( klass != null ) {
108
- Type [ ] cArg = new Type [ ] { typeof ( String ) } ;
109
- MethodInfo m = klass . GetMethod ( licenseeInfoMethodName , cArg ) ;
110
- String coreVersion = release ;
111
- Object [ ] args = new Object [ ] { coreVersion } ;
112
- String [ ] info = ( String [ ] ) m . Invoke ( System . Activator . CreateInstance ( klass ) , args ) ;
105
+ String coreVersion = release ;
106
+ String [ ] info = GetLicenseeInfoFromLicenseKey ( coreVersion ) ;
107
+ if ( info != null ) {
113
108
if ( info [ 3 ] != null && info [ 3 ] . Trim ( ) . Length > 0 ) {
114
109
version . key = info [ 3 ] ;
115
110
}
@@ -124,13 +119,12 @@ public static iText.Kernel.Version GetInstance() {
124
119
}
125
120
if ( info . Length > 6 ) {
126
121
if ( info [ 6 ] != null && info [ 6 ] . Trim ( ) . Length > 0 ) {
127
- if ( ! release . StartsWith ( info [ 6 ] ) ) {
128
- throw new ArgumentException ( "Your license key version doesn't match the iText version." ) ;
129
- }
122
+ //Compare versions with this release versions
123
+ CheckLicenseVersion ( coreVersion , info [ 6 ] ) ;
130
124
}
131
125
}
132
126
if ( info [ 4 ] != null && info [ 4 ] . Trim ( ) . Length > 0 ) {
133
- version . iTextVersion = info [ 4 ] ;
127
+ version . producerLine = info [ 4 ] ;
134
128
}
135
129
else {
136
130
if ( info [ 2 ] != null && info [ 2 ] . Trim ( ) . Length > 0 ) {
@@ -153,10 +147,24 @@ public static iText.Kernel.Version GetInstance() {
153
147
version . AddAGPLPostfix ( null ) ;
154
148
}
155
149
}
156
- catch ( ArgumentException iae ) {
157
- version . AddAGPLPostfix ( iae . InnerException ) ;
150
+ catch ( LicenseVersionException lve ) {
151
+ //Catch the exception
152
+ //Rethrow license version exceptions
153
+ throw ;
154
+ }
155
+ catch ( TypeLoadException ) {
156
+ //License key library not on classpath, switch to AGPL
157
+ version . AddAGPLPostfix ( null ) ;
158
158
}
159
159
catch ( Exception e ) {
160
+ //Check if an iText5 license is loaded
161
+ if ( e . InnerException != null && e . InnerException . Message . Equals ( LicenseVersionException . LICENSE_FILE_NOT_LOADED
162
+ ) ) {
163
+ if ( IsiText5licenseLoaded ( ) ) {
164
+ throw new LicenseVersionException ( LicenseVersionException . NO_I_TEXT7_LICENSE_IS_LOADED_BUT_AN_I_TEXT5_LICENSE_IS_LOADED
165
+ ) ;
166
+ }
167
+ }
160
168
version . AddAGPLPostfix ( e . InnerException ) ;
161
169
}
162
170
}
@@ -184,7 +192,7 @@ public static bool IsExpired() {
184
192
/// </remarks>
185
193
/// <returns>the product name</returns>
186
194
public String GetProduct ( ) {
187
- return iText ;
195
+ return iTextProductName ;
188
196
}
189
197
190
198
/// <summary>Gets the release number.</summary>
@@ -207,7 +215,7 @@ public String GetRelease() {
207
215
/// </remarks>
208
216
/// <returns>iText version</returns>
209
217
public String GetVersion ( ) {
210
- return iTextVersion ;
218
+ return producerLine ;
211
219
}
212
220
213
221
/// <summary>Returns a license key if one was provided, or null if not.</summary>
@@ -217,22 +225,113 @@ public String GetKey() {
217
225
}
218
226
219
227
private void AddLicensedPostfix ( String ownerName ) {
220
- iTextVersion += " (" + ownerName ;
228
+ producerLine += " (" + ownerName ;
221
229
if ( ! key . ToLowerInvariant ( ) . StartsWith ( "trial" ) ) {
222
- iTextVersion += "; licensed version)" ;
230
+ producerLine += "; licensed version)" ;
223
231
}
224
232
else {
225
- iTextVersion += "; " + key + ")" ;
233
+ producerLine += "; " + key + ")" ;
226
234
}
227
235
}
228
236
229
237
private void AddAGPLPostfix ( Exception cause ) {
230
- iTextVersion += AGPL ;
238
+ producerLine += AGPL ;
231
239
if ( cause != null && cause . Message != null && cause . Message . Contains ( "expired" ) ) {
232
240
expired = true ;
233
241
}
234
242
}
235
243
244
+ private static void CheckLicenseVersion ( String coreVersionString , String licenseVersionString ) {
245
+ String [ ] coreVersions = ParseVersionString ( coreVersionString ) ;
246
+ String [ ] licenseVersions = ParseVersionString ( licenseVersionString ) ;
247
+ int coreMajor = System . Convert . ToInt32 ( coreVersions [ 0 ] ) ;
248
+ int coreMinor = System . Convert . ToInt32 ( coreVersions [ 1 ] ) ;
249
+ int licenseMajor = System . Convert . ToInt32 ( licenseVersions [ 0 ] ) ;
250
+ int licenseMinor = System . Convert . ToInt32 ( licenseVersions [ 1 ] ) ;
251
+ //Major version check
252
+ if ( licenseMajor < coreMajor ) {
253
+ throw new LicenseVersionException ( LicenseVersionException . THE_MAJOR_VERSION_OF_THE_LICENSE_0_IS_LOWER_THAN_THE_MAJOR_VERSION_1_OF_THE_CORE_LIBRARY
254
+ ) . SetMessageParams ( licenseMajor , coreMajor ) ;
255
+ }
256
+ if ( licenseMajor > coreMajor ) {
257
+ throw new LicenseVersionException ( LicenseVersionException . THE_MAJOR_VERSION_OF_THE_LICENSE_0_IS_HIGHER_THAN_THE_MAJOR_VERSION_1_OF_THE_CORE_LIBRARY
258
+ ) . SetMessageParams ( licenseMajor , coreMajor ) ;
259
+ }
260
+ //Minor version check
261
+ if ( licenseMinor < coreMinor ) {
262
+ throw new LicenseVersionException ( LicenseVersionException . THE_MINOR_VERSION_OF_THE_LICENSE_0_IS_LOWER_THAN_THE_MINOR_VERSION_1_OF_THE_CORE_LIBRARY
263
+ ) . SetMessageParams ( licenseMinor , coreMinor ) ;
264
+ }
265
+ }
266
+
267
+ private static String [ ] ParseVersionString ( String version ) {
268
+ String splitRegex = "\\ ." ;
269
+ String [ ] split = iText . IO . Util . StringUtil . Split ( version , splitRegex ) ;
270
+ //Guard for empty versions and throw exceptions
271
+ if ( split . Length == 0 ) {
272
+ throw new LicenseVersionException ( LicenseVersionException . VERSION_STRING_IS_EMPTY_AND_CANNOT_BE_PARSED ) ;
273
+ }
274
+ //Desired Format: X.Y.Z-....
275
+ //Also catch X, X.Y-...
276
+ String major = split [ 0 ] ;
277
+ String minor = "0" ;
278
+ //If no minor version is present, default to 0
279
+ if ( split . Length > 1 ) {
280
+ minor = split [ 1 ] . Substring ( 0 ) ;
281
+ }
282
+ //Check if both values are numbers
283
+ if ( ! IsVersionNumeric ( major ) ) {
284
+ throw new LicenseVersionException ( LicenseVersionException . MAJOR_VERSION_IS_NOT_NUMERIC ) ;
285
+ }
286
+ if ( ! IsVersionNumeric ( minor ) ) {
287
+ throw new LicenseVersionException ( LicenseVersionException . MINOR_VERSION_IS_NOT_NUMERIC ) ;
288
+ }
289
+ return new String [ ] { major , minor } ;
290
+ }
291
+
292
+ /// <exception cref="System.TypeLoadException"/>
293
+ /// <exception cref="System.MissingMethodException"/>
294
+ /// <exception cref="System.MemberAccessException"/>
295
+ /// <exception cref="Java.Lang.InstantiationException"/>
296
+ /// <exception cref="System.Reflection.TargetInvocationException"/>
297
+ private static String [ ] GetLicenseeInfoFromLicenseKey ( String validatorKey ) {
298
+ String licenseeInfoMethodName = "getLicenseeInfoForVersion" ;
299
+ Type klass = GetLicenseKeyClass ( ) ;
300
+ if ( klass != null ) {
301
+ Type [ ] cArg = new Type [ ] { typeof ( String ) } ;
302
+ MethodInfo m = klass . GetMethod ( licenseeInfoMethodName , cArg ) ;
303
+ Object [ ] args = new Object [ ] { validatorKey } ;
304
+ String [ ] info = ( String [ ] ) m . Invoke ( System . Activator . CreateInstance ( klass ) , args ) ;
305
+ return info ;
306
+ }
307
+ return null ;
308
+ }
309
+
310
+ private static bool IsiText5licenseLoaded ( ) {
311
+ String validatorKey5 = "5" ;
312
+ bool result = false ;
313
+ try {
314
+ String [ ] info = GetLicenseeInfoFromLicenseKey ( validatorKey5 ) ;
315
+ result = true ;
316
+ }
317
+ catch ( Exception ) {
318
+ }
319
+ //TODO: Log this exception?
320
+ return result ;
321
+ }
322
+
323
+ private static bool IsVersionNumeric ( String version ) {
324
+ //I did not want to introduce an extra dependency on apache.commons in order to use StringUtils.
325
+ //This small method is not the most optimal, but it should do for release
326
+ try {
327
+ System . Double . Parse ( version , System . Globalization . CultureInfo . InvariantCulture ) ;
328
+ return true ;
329
+ }
330
+ catch ( FormatException ) {
331
+ return false ;
332
+ }
333
+ }
334
+
236
335
private static Type GetLicenseKeyClass ( ) {
237
336
String licenseKeyClassPartialName = "iText.License.LicenseKey, itext.licensekey" ;
238
337
String licenseKeyClassFullName = null ;
0 commit comments