@Override public Token tokenizeOnly(Text text, ObjectSupply objectSupply) throws SyntaxErrorException { Token leading = this.leader.tokenizeOnly(text, objectSupply); if (leading == null) { return null; } TSequence foundTokens = objectSupply.newSequence(this.getMaxSequenceCount()); foundTokens.addToken(leading); if (text.onChar()) { int textIndex = text.getIndex(); for (TFSequence follower : this.followers) { foundTokens.resetIndex(1); Token result = follower.tokenizeCommon(text, objectSupply, 1, foundTokens, true); if (result != null) { TokenFactory f0th = follower.getFactory(0); Token replaced = f0th.convert(leading); foundTokens.set(0, replaced); foundTokens.setLength(follower.getSequenceCount()); return follower.convert(result); } text.resetIndex(textIndex); } } else { for (TFSequence follower : this.followers) { if (follower.validateEnd(0, foundTokens, true)) { return follower.convert(foundTokens); } } } if (this.singleValid) { return this.leader.convert(leading); } throw new SyntaxErrorException(); }
/** {@inheritDoc} */ public void addNullToken() { if (firstToken == null) { firstToken = tokenFactory.createToken(); currentToken = firstToken; } else { currentToken.setNextToken(tokenFactory.createToken()); previousToken = currentToken; currentToken = currentToken.getNextToken(); } }
/** * Adds the token specified to the current linked list of tokens. * * @param array The character array. * @param start The starting offset in the array. * @param end The ending offset in the array. * @param tokenType The token's type. * @param startOffset The offset in the document at which this token occurs. * @param hyperlink Whether this token is a hyperlink. */ public void addToken( char[] array, int start, int end, int tokenType, int startOffset, boolean hyperlink) { if (firstToken == null) { firstToken = tokenFactory.createToken(array, start, end, startOffset, tokenType); currentToken = firstToken; // previous token is still null. } else { currentToken.setNextToken( tokenFactory.createToken(array, start, end, startOffset, tokenType)); previousToken = currentToken; currentToken = currentToken.getNextToken(); } currentToken.setHyperlink(hyperlink); }
/** * Create a new user ID token from the provided JSON object. The associated master token must be * provided to verify the user ID token. * * @param ctx MSL context. * @param userIdTokenJO user ID token JSON object. * @param masterToken the master token. * @throws MslEncodingException if there is an error parsing the JSON, the token data is missing * or invalid, or the signature is invalid. * @throws MslCryptoException if there is an error verifying the token data. * @throws MslException if the user ID token master token serial number does not match the master * token serial number, or the expiration timestamp occurs before the renewal window, or the * user data is missing or invalid, or the user ID token master token serial number is out of * range, or the user ID token serial number is out of range. */ public UserIdToken( final MslContext ctx, final JSONObject userIdTokenJO, final MasterToken masterToken) throws MslEncodingException, MslCryptoException, MslException { this.ctx = ctx; // Grab the crypto context. final ICryptoContext cryptoContext = ctx.getMslCryptoContext(); // Verify the JSON representation. try { try { tokendata = Base64.decode(userIdTokenJO.getString(KEY_TOKENDATA)); } catch (final IllegalArgumentException e) { throw new MslEncodingException( MslError.USERIDTOKEN_TOKENDATA_INVALID, "useridtoken " + userIdTokenJO.toString(), e) .setMasterToken(masterToken); } if (tokendata == null || tokendata.length == 0) throw new MslEncodingException( MslError.USERIDTOKEN_TOKENDATA_MISSING, "useridtoken " + userIdTokenJO.toString()) .setMasterToken(masterToken); try { signature = Base64.decode(userIdTokenJO.getString(KEY_SIGNATURE)); } catch (final IllegalArgumentException e) { throw new MslEncodingException( MslError.USERIDTOKEN_SIGNATURE_INVALID, "useridtoken " + userIdTokenJO.toString(), e) .setMasterToken(masterToken); } verified = cryptoContext.verify(tokendata, signature); } catch (final JSONException e) { throw new MslEncodingException( MslError.JSON_PARSE_ERROR, "useridtoken " + userIdTokenJO.toString(), e) .setMasterToken(masterToken); } // Pull the token data. final String tokenDataJson = new String(tokendata, MslConstants.DEFAULT_CHARSET); try { final JSONObject tokenDataJO = new JSONObject(tokenDataJson); renewalWindow = tokenDataJO.getLong(KEY_RENEWAL_WINDOW); expiration = tokenDataJO.getLong(KEY_EXPIRATION); if (expiration < renewalWindow) throw new MslException( MslError.USERIDTOKEN_EXPIRES_BEFORE_RENEWAL, "usertokendata " + tokenDataJson) .setMasterToken(masterToken); mtSerialNumber = tokenDataJO.getLong(KEY_MASTER_TOKEN_SERIAL_NUMBER); if (mtSerialNumber < 0 || mtSerialNumber > MslConstants.MAX_LONG_VALUE) throw new MslException( MslError.USERIDTOKEN_MASTERTOKEN_SERIAL_NUMBER_OUT_OF_RANGE, "usertokendata " + tokenDataJson) .setMasterToken(masterToken); serialNumber = tokenDataJO.getLong(KEY_SERIAL_NUMBER); if (serialNumber < 0 || serialNumber > MslConstants.MAX_LONG_VALUE) throw new MslException( MslError.USERIDTOKEN_SERIAL_NUMBER_OUT_OF_RANGE, "usertokendata " + tokenDataJson) .setMasterToken(masterToken); final byte[] ciphertext; try { ciphertext = Base64.decode(tokenDataJO.getString(KEY_USERDATA)); } catch (final IllegalArgumentException e) { throw new MslException( MslError.USERIDTOKEN_USERDATA_INVALID, tokenDataJO.getString(KEY_USERDATA)) .setMasterToken(masterToken); } if (ciphertext == null || ciphertext.length == 0) throw new MslException( MslError.USERIDTOKEN_USERDATA_MISSING, tokenDataJO.getString(KEY_USERDATA)) .setMasterToken(masterToken); userdata = (verified) ? cryptoContext.decrypt(ciphertext) : null; } catch (final JSONException e) { throw new MslEncodingException( MslError.USERIDTOKEN_TOKENDATA_PARSE_ERROR, "usertokendata " + tokenDataJson, e) .setMasterToken(masterToken); } catch (final MslCryptoException e) { e.setMasterToken(masterToken); throw e; } // Pull the user data. if (userdata != null) { final String userDataJson = new String(userdata, MslConstants.DEFAULT_CHARSET); try { final JSONObject userDataJO = new JSONObject(userDataJson); issuerData = (userDataJO.has(KEY_ISSUER_DATA)) ? userDataJO.getJSONObject(KEY_ISSUER_DATA) : null; final String identity = userDataJO.getString(KEY_IDENTITY); if (identity == null || identity.length() == 0) throw new MslException(MslError.USERIDTOKEN_IDENTITY_INVALID, "userdata " + userDataJson) .setMasterToken(masterToken); final TokenFactory factory = ctx.getTokenFactory(); user = factory.createUser(ctx, identity); if (user == null) throw new MslInternalException( "TokenFactory.createUser() returned null in violation of the interface contract."); } catch (final JSONException e) { throw new MslEncodingException( MslError.USERIDTOKEN_USERDATA_PARSE_ERROR, "userdata " + userDataJson, e) .setMasterToken(masterToken); } } else { issuerData = null; user = null; } // Verify serial numbers. if (masterToken == null || this.mtSerialNumber != masterToken.getSerialNumber()) throw new MslException( MslError.USERIDTOKEN_MASTERTOKEN_MISMATCH, "uit mtserialnumber " + this.mtSerialNumber + "; mt " + masterToken) .setMasterToken(masterToken); }
/** * Deletes the linked list of tokens so we can begin anew. This should never have to be called by * the programmer, as it is automatically called whenever the user calls {@link * #getLastTokenTypeOnLine(Segment, int)} or {@link #getTokenList(Segment, int, int)}. */ protected void resetTokenList() { firstToken = currentToken = previousToken = null; tokenFactory.resetAllTokens(); }