List of usage examples for java.util.concurrent.atomic AtomicReference get
public final V get()
From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java
/** * Undoes pending changes for matching items in this workspace. Items in * working folders are immediately updated. If <code>updateDisk</code> is * <code>false</code>, then the files on disk will not be updated in * response to the server commands to do so. Passing <code>false</code> for * <code>updateDisk</code> is not common and should only be needed in rare * situations.//w ww . j av a2 s . c o m * <p> * <!-- Event Origination Info --> * <p> * This method is an <b>core event origination point</b>. The * {@link EventSource} object that accompanies each event fired by this * method describes the execution context (current thread, etc.) when and * where this method was invoked. * * @param items * the items to undo (must not be <code>null</code>) * @param getOptions * the {@link GetOptions} to use (must not be <code>null</code>) * @param deleteAdds * determines if adds should be deleted * @param itemPropertyFilters * a list of versioned item properties to return with each get * operation (may be <code>null</code>) * @return the number of items successfully undone. */ public int undo(final ItemSpec[] items, final GetOptions getOptions, final boolean deleteAdds, String[] itemPropertyFilters) { Check.notNull(items, "items"); //$NON-NLS-1$ // Using web service directly so merge filters configured on client itemPropertyFilters = client.mergeWithDefaultItemPropertyFilters(itemPropertyFilters); client.getEventEngine() .fireOperationStarted(new UndoOperationStartedEvent(EventSource.newFromHere(), this, items)); int ret = 0; try { if (items.length == 0) { return 0; } final AtomicReference<Failure[]> failuresHolder = new AtomicReference<Failure[]>(); final AtomicBoolean onlineOperationHolder = new AtomicBoolean(); final AtomicReference<ChangePendedFlags> changePendedFlagsHolder = new AtomicReference<ChangePendedFlags>(); final GetOperation[] operations = client.getWebServiceLayer().undoPendingChanges(getName(), getOwnerName(), items, failuresHolder, null, itemPropertyFilters, onlineOperationHolder, false, changePendedFlagsHolder); if (operations != null && operations.length > 0) { if (isLocal()) { final GetEngine getEngine = new GetEngine(client); getEngine.processGetOperations(this, ProcessType.UNDO, RequestType.NONE, new GetOperation[][] { operations }, getOptions, deleteAdds, onlineOperationHolder.get(), changePendedFlagsHolder.get()); ret = operations.length; } else { final String messageFormat = Messages .getString("Workspace.OperationCompletedForRemoteWorkspaceButGetRequiredFormat"); //$NON-NLS-1$ final String message = MessageFormat.format(messageFormat, getDisplayName()); client.getEventEngine().fireNonFatalError( new NonFatalErrorEvent(EventSource.newFromHere(), this, new Exception(message))); } } if (changePendedFlagsHolder.get().contains(ChangePendedFlags.WORKING_FOLDER_MAPPINGS_UPDATED)) { invalidateMappings(); } client.reportFailures(this, failuresHolder.get()); } finally { client.getEventEngine().fireOperationCompleted( new UndoOperationCompletedEvent(EventSource.newFromHere(), this, items)); Workstation.getCurrent(getClient().getConnection().getPersistenceStoreProvider()) .notifyForWorkspace(this, Notification.VERSION_CONTROL_PENDING_CHANGES_CHANGED); } return ret; }
From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java
/** * Unshelves changes, restoring them to the workspace. * * @param shelvesetName/*w w w. ja v a 2 s .c om*/ * the name of the shelveset to restore (must not be * <code>null</code> or empty). * @param shelvesetOwner * the owner of the shelveset to restore (must not be * <code>null</code> or empty). * @param itemSpecs * the items to restore. If this array is null, all changes in the * named shelveset are restored. If this array is empty, no changes * will be unshelved. * @param itemPropertyFilters * a list of versioned item properties to return with each get * operation (may be <code>null</code>) * @param shelvesetPropertyFilters * the list of properties to be returned on the shelvesets. To get * all properties pass a single filter that is simply "*" (may be * <code>null</code>) * @param merge * <code>true</code> to allow merging conflicting changes in the * shelveset with local pending changes ({@link Conflict}s will be * produced) * @param noAutoResolve * <code>true</code> to disable automerging of conflicting changes, * <code>false</code> to perform an automerge * @return the {@link UnshelveResult} which contains the {@link Shelveset} * unshelved and the {@link GetStatus} for the get operations which * were processed, or <code>null</code> if the unshelve operation * failed with no further status from the server */ public UnshelveResult unshelve(final String shelvesetName, final String shelvesetOwner, final ItemSpec[] itemSpecs, String[] itemPropertyFilters, final String[] shelvesetPropertyFilters, final boolean merge, final boolean noAutoResolve) throws UnshelveException { Check.notNullOrEmpty(shelvesetName, "shelvesetName"); //$NON-NLS-1$ Check.notNullOrEmpty(shelvesetOwner, "shelvesetOwner"); //$NON-NLS-1$ log.debug("Unshelve started."); //$NON-NLS-1$ final AtomicReference<Failure[]> failuresHolder = new AtomicReference<Failure[]>(); final AtomicReference<GetOperation[]> getOperationsHolder = new AtomicReference<GetOperation[]>(); final AtomicReference<Conflict[]> conflictsHolder = new AtomicReference<Conflict[]>(); final AtomicReference<ChangePendedFlags> changePendedFlagsHolder = new AtomicReference<ChangePendedFlags>(); // Using web service directly so merge filters configured on client itemPropertyFilters = client.mergeWithDefaultItemPropertyFilters(itemPropertyFilters); final Shelveset shelveset = client.getWebServiceLayer().unshelve(shelvesetName, shelvesetOwner, getName(), getOwnerName(), itemSpecs, null, itemPropertyFilters, shelvesetPropertyFilters, merge, failuresHolder, getOperationsHolder, conflictsHolder, changePendedFlagsHolder); log.debug("Preparing get operations."); //$NON-NLS-1$ /* * Print out any failures and bail if there were any serious errors. */ if (failuresHolder.get().length > 0) { client.reportFailures(this, failuresHolder.get()); if (getOperationsHolder.get().length == 0) { throw new UnshelveException(Messages.getString("Workspace.NoChangesUnshelved")); //$NON-NLS-1$ } } /* * Turns out that the result.value can be null if the unshelve fails. In * which case return null and let the caller display the error message * that will have been thrown from the above events. */ if (shelveset == null) { return null; } final GetOperation[] getOperations = getOperationsHolder.get(); Conflict[] conflicts = conflictsHolder.get(); /* * Convert the get operations into pending changes so we can pass them * through the event. */ final PendingChange[] unshelvedChanges = getOperations != null ? new PendingChange[getOperations.length] : new PendingChange[0]; if (getOperations != null && getOperations.length > 0) { for (int i = 0; i < getOperations.length; i++) { getOperations[i].setProcessType(ProcessType.UNSHELVE); unshelvedChanges[i] = new PendingChange(this, getOperations[i], ProcessType.UNSHELVE); } } client.getEventEngine().fireOperationStarted( new UnshelveShelvesetStartedEvent(EventSource.newFromHere(), this, shelveset, unshelvedChanges)); GetStatus getStatus = new GetStatus(); try { if (getOperations != null && getOperations.length > 0) { final GetEngine getEngine = new GetEngine(client); getStatus = getEngine.processGetOperations(this, ProcessType.UNSHELVE, getOperations, GetOptions.NONE, changePendedFlagsHolder.get()); } /* We want to auto resolve conflicts if the option is set */ int resolvedConflicts = 0; if (conflicts != null && !noAutoResolve) { /* Actually auto resolve the conflicts */ final Conflict[] remainingConflicts = client.autoResolveValidConflicts(this, conflicts, AutoResolveOptions.ALL_SILENT); resolvedConflicts = conflicts.length - remainingConflicts.length; conflicts = remainingConflicts; } /* Fire events for conflicts found during the unshelve. */ int nonResolvedConflicts = 0; if (conflicts != null) { for (final Conflict conflict : conflicts) { if (conflict.getResolution() == Resolution.NONE) { nonResolvedConflicts++; client.getEventEngine().fireConflict(new ConflictEvent(EventSource.newFromHere(), conflict.getYourServerItemSource(), this, ConflictDescriptionFactory.getConflictDescription( ConflictCategory.getConflictCategory(conflict), conflict).getDescription(), true)); } } } getStatus.setNumConflicts(getStatus.getNumConflicts() + nonResolvedConflicts); getStatus.setNumResolvedConflicts(resolvedConflicts); } finally { client.getEventEngine().fireOperationCompleted(new UnshelveShelvesetCompletedEvent( EventSource.newFromHere(), this, shelveset, unshelvedChanges)); Workstation.getCurrent(getClient().getConnection().getPersistenceStoreProvider()) .notifyForWorkspace(this, Notification.VERSION_CONTROL_PENDING_CHANGES_CHANGED); } if (changePendedFlagsHolder.get().contains(ChangePendedFlags.WORKING_FOLDER_MAPPINGS_UPDATED)) { invalidateMappings(); } return new UnshelveResult(shelveset, getStatus, unshelvedChanges, conflicts); }
From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java
/** * Merge changes made between two versions to items in a given source path * into a given target path. The result of this method is that one or more * merge items are pended./*from ww w .j av a 2 s. c om*/ * <p> * <!-- Event Origination Info --> * <p> * This method is an <b>core event origination point</b>. The * {@link EventSource} object that accompanies each event fired by this * method describes the execution context (current thread, etc.) when and * where this method was invoked. * * @param sourceSpec * the local or server path of the source of the merge; where the * changes are copied from, and the recursion type to match the given * source path with (must not be <code>null</code>, path must not be * <code>null</code> or empty) * @param targetPath * the local or server path of the target of the merge; where the * changes will end up (must not be <code>null</code> or empty). * @param sourceVersionFrom * the version (inclusive) of the source item to start including * changes from for this merge operation. null indicates all versions * beginning with version 1. * @param sourceVersionTo * the version (inclusive) of the source item to stop including * changes from for this merge operation. null indicates all versions * up to and including tip version. * @param lockLevel * the lock level to apply to the pended changes (must not be * <code>null</code>) * @param mergeFlags * any merge options to apply during this merge (must not be * <code>null</code>) * @param itemPropertyFilters * a list of versioned item properties to return with each get * operation (may be <code>null</code>) * @return a GetStatus instance with the results of the merge operation. */ public GetStatus merge(final ItemSpec sourceSpec, final String targetPath, final VersionSpec sourceVersionFrom, final VersionSpec sourceVersionTo, final LockLevel lockLevel, final MergeFlags mergeFlags, String[] itemPropertyFilters) { Check.notNull(sourceSpec, "sourceSpec"); //$NON-NLS-1$ Check.notNullOrEmpty(sourceSpec.getItem(), "sourceSpec.item"); //$NON-NLS-1$ Check.notNull(sourceSpec.getRecursionType(), "sourceSpec.recursion"); //$NON-NLS-1$ Check.notNullOrEmpty(targetPath, "targetPath"); //$NON-NLS-1$ Check.notNull(lockLevel, "lockLevel"); //$NON-NLS-1$ Check.notNull(mergeFlags, "mergeFlags"); //$NON-NLS-1$ // Using web service directly so merge filters configured on client itemPropertyFilters = client.mergeWithDefaultItemPropertyFilters(itemPropertyFilters); final ItemSpec targetSpec = new ItemSpec(targetPath, RecursionType.NONE); int nonResolvedConflicts = 0; int resolvedConflicts = 0; client.getEventEngine() .fireOperationStarted(new MergeOperationStartedEvent(EventSource.newFromHere(), this)); final AtomicReference<Failure[]> failures = new AtomicReference<Failure[]>(); final AtomicReference<Conflict[]> conflicts = new AtomicReference<Conflict[]>(); final AtomicReference<ChangePendedFlags> changePendedFlags = new AtomicReference<ChangePendedFlags>(); try { final GetOperation[] getOps = client.getWebServiceLayer().merge(getName(), getOwnerName(), sourceSpec, targetSpec, sourceVersionFrom, sourceVersionTo, lockLevel, mergeFlags, failures, conflicts, null, itemPropertyFilters, changePendedFlags); final boolean discard = mergeFlags.contains(MergeFlags.ALWAYS_ACCEPT_MINE); // Match up these getOps and merge details (returned as Conflict // objects). The conflicts with matching getOps have already been // resolved. final Map<String, Conflict> pathConflictDict = new TreeMap<String, Conflict>( ServerPath.TOP_DOWN_COMPARATOR); final Map<Integer, Conflict> itemIdConflictDict = new HashMap<Integer, Conflict>(); for (final Conflict conflict : conflicts.get()) { if (conflict.isResolved()) { // if it is a branch, and the user asked for preview, we do // not assign ItemIds // so we need to lookup by path if (conflict.getBaseChangeType().contains(ChangeType.BRANCH) && conflict.getYourItemID() == 0) { pathConflictDict.put(conflict.getYourServerItem(), conflict); } else { itemIdConflictDict.put(conflict.getYourItemID(), conflict); } } } for (final GetOperation getOp : getOps) { if (getOp.getChangeType().contains(ChangeType.BRANCH) && getOp.getItemID() == 0) { final Conflict conflict = pathConflictDict.get(getOp.getTargetServerItem()); if (conflict != null) { getOp.setMergeDetails(conflict); } } else { final Conflict conflict = itemIdConflictDict.get(getOp.getItemID()); if (conflict != null) { getOp.setMergeDetails(conflict); } } } GetStatus getStatus = null; if (isLocal()) { /* * We want to auto resolve conflicts if the option is set to do * so and we are not discarding */ if (!discard && !mergeFlags.contains(MergeFlags.NO_AUTO_RESOLVE) && !mergeFlags.contains(MergeFlags.NO_MERGE)) { if (getClient().getWebServiceLayer().getServiceLevel().getValue() < WebServiceLevel.TFS_2012_1 .getValue()) { /* * The download urls for base files were not populated * on conflicts in pre 2012 servers. Let's call * QueryConflicts now so that we have that information. * We use sourceSpec.RecursionType here because that * corresponds to what the user passed in. */ conflicts.set(queryConflicts(new String[] { targetSpec.getItem() }, sourceSpec.getRecursionType() != RecursionType.NONE)); } final Conflict[] remainingConflicts = getClient().autoResolveValidConflicts(this, conflicts.get(), AutoResolveOptions.ALL_SILENT); resolvedConflicts = conflicts.get().length - remainingConflicts.length; conflicts.set(remainingConflicts); } // Fire events for merges that did not get resolved by the // server. // The others will get fired in get.cs as they are processed. for (final Conflict conflict : conflicts.get()) { if (conflict.getResolution() == Resolution.NONE) { log.trace("Firing event on conflict: " + conflict); //$NON-NLS-1$ // The pending change arg is null because of the // conflict. client.getEventEngine() .fireMerging(new MergingEvent(EventSource.newFromHere(), new Conflict(conflict), this, false, null, OperationStatus.CONFLICT, ChangeType.NONE, true, new PropertyValue[0])); nonResolvedConflicts++; } } // When we are discarding source changes, we simply call // ResolveConflict. if (discard) { for (final Conflict conflict : conflicts.get()) { // There is nothing to do when the resolution is // AcceptYours. client.getEventEngine().fireConflictResolved(new ConflictResolvedEvent( EventSource.newFromHere(), this, conflict, changePendedFlags.get())); } getStatus = new GetStatus(); getStatus.setNumOperations(conflicts.get().length); return getStatus; } final GetOptions options = mergeFlags.contains(MergeFlags.NO_MERGE) ? GetOptions.PREVIEW : GetOptions.NONE; final GetEngine getEngine = new GetEngine(client); getStatus = getEngine.processGetOperations(this, ProcessType.MERGE, getOps, options, changePendedFlags.get()); getStatus.setNumConflicts(getStatus.getNumConflicts() + nonResolvedConflicts); getStatus.setNumResolvedConflicts(resolvedConflicts); } else if (getOps.length > 0) { client.getEventEngine() .fireNonFatalError(new NonFatalErrorEvent(EventSource.newFromHere(), this, new VersionControlException(MessageFormat.format( Messages.getString("Workspace.NoLocalChangesRemoteWorkspaceFormat"), //$NON-NLS-1$ getDisplayName())))); } if (getStatus == null) { getStatus = new GetStatus(); getStatus.setNumOperations(getOps.length); } if (changePendedFlags.get().contains(ChangePendedFlags.WORKING_FOLDER_MAPPINGS_UPDATED)) { invalidateMappings(); } client.reportFailures(this, failures.get()); for (final Failure failure : failures.get()) { getStatus.addFailure(failure); } return getStatus; } finally { client.getEventEngine() .fireOperationCompleted(new MergeOperationCompletedEvent(EventSource.newFromHere(), this)); Workstation.getCurrent(getClient().getConnection().getPersistenceStoreProvider()) .notifyForWorkspace(this, Notification.VERSION_CONTROL_PENDING_CHANGES_CHANGED); } }
From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java
/** * Checkin pending changes in this workspace. * <p>// w ww. java 2 s . co m * <!-- Event Origination Info --> * <p> * This method is an <b>core event origination point</b>. The * {@link EventSource} object that accompanies each event fired by this * method describes the execution context (current thread, etc.) when and * where this method was invoked. * * @param changes * the changes to checkin (may be <code>null</code> to have the * server check in all changes in this workspace) * @param committer * if not <code>null</code>, the committer of this change. if * <code>null</code>, the committer will be the authenticated user. * @param author * if not <code>null</code>, the author of this change. if * <code>null</code>, the author will be the authenticated user. * @param comment * a text comment that will be associated with this checkin (can be * <code>null</code>). * @param checkinNote * {@link CheckinNote} object containing array of * ACheckinNoteFieldValue objects. If <code>null</code>, no checkin * notes are added to changeset. For a list of checkin note field * names applicable to the items use the * queryCheckinNoteFieldDefinitionsForServerPaths on the * VersionControlClient. * @param associatedWorkItems * work items to associate with the checkin. if <code>null</code>, no * work items are associated with this checkin * @param policyOverrideInfo * Optional information describing why checkin policies were * overridden for this checkin. Pass null for a normal check-in * (policies were not overridden). * @param flags * {@link CheckinFlags} which control the checkin (must not be * <code>null</code>) * @return the changeset number the server chooses for this changeset. * @throws CheckinException * if conflicts caused the checkin to fail or if other errors * occurred. * @throws ActionDeniedBySubscriberException * if the check-in was denied by the server (because of a gated * build definition, etc.). * * @see VersionControlClient#queryCheckinNoteFieldDefinitionsForServerPaths(String[]) */ public int checkIn(PendingChange[] changes, final String committer, final String committerDisplayName, String author, String authorDisplayName, final String comment, final CheckinNote checkinNote, WorkItemCheckinInfo[] associatedWorkItems, final PolicyOverrideInfo policyOverrideInfo, final CheckinFlags flags) throws CheckinException { Check.isTrue(changes == null || changes.length > 0, "changes must be null for server-side change selection or non-empty"); //$NON-NLS-1$ Check.notNull(flags, "flags"); //$NON-NLS-1$ /** * TFS 2010 behaves strangely with gated check-ins if we send null for * associated work items (a non-standard subcode comes back in the * ActionDeniedBySubscriberException. Always send at least an empty * list. */ if (associatedWorkItems == null) { associatedWorkItems = new WorkItemCheckinInfo[0]; } final TaskMonitor monitor = TaskMonitorService.getTaskMonitor(); /* * The total work for our progress monitor is set to 100, and subtasks * are allocated as percentages. For example, checkin for conflicts is * quick, so it takes only 2 percent. Uploading files usually takes * longer, so it's 80 percent. Make sure all the work done in this * method adds to 100. */ monitor.begin("", 100); //$NON-NLS-1$ /* * We sort the changes by server path so they appear in the correct * order when giving status information to the user. */ String[] serverItems = null; if (changes != null) { changes = changes.clone(); Arrays.sort(changes, new PendingChangeComparator(PendingChangeComparatorType.SERVER_ITEM)); serverItems = PendingChange.toServerItems(changes); } // Lets us detect all abnormal exits (Throwable, Exception, Gated // checkin exception) for saved checkin reset boolean success = false; try { TaskMonitorService.pushTaskMonitor(monitor.newSubTaskMonitor(75)); try { // Upload contents if (changes != null) { final CheckinEngine ci = new CheckinEngine(client, this); final long start = System.currentTimeMillis(); ci.uploadChanges(changes, false, getLocation() == WorkspaceLocation.LOCAL); log.debug(MessageFormat.format("total time for upload of {0} was {1} ms", //$NON-NLS-1$ changes.length, (System.currentTimeMillis() - start))); } else { log.debug("null changes (server side change selection), skipped upload"); //$NON-NLS-1$ } } finally { TaskMonitorService.popTaskMonitor(true); } if (author == null) { author = VersionControlConstants.AUTHENTICATED_USER; } if (authorDisplayName == null) { authorDisplayName = UserNameUtil.getCurrentUserName(); final String domainName = UserNameUtil.getCurrentUserDomain(); if (!StringUtil.isNullOrEmpty(domainName)) { authorDisplayName = UserNameUtil.format(authorDisplayName, domainName); } } /* * Finally, create a Changeset and send it to the server to be * committed. It's important to pass "null" for the date so TFS 2010 * and later do not require CheckinOther permissions (required to * set a specific date on a new changeset). */ final Changeset changeset = new Changeset(null, comment, checkinNote, policyOverrideInfo, committer, committerDisplayName, null, -1, author, authorDisplayName, null); /* * Test one final time before the change set is fully committed. */ if (monitor.isCanceled()) { // Caught in this method below. throw new CoreCancelException(); } monitor.setCurrentWorkDescription(Messages.getString("Workspace.CheckinInNewChangeset")); //$NON-NLS-1$ final AtomicReference<Failure[]> failures = new AtomicReference<Failure[]>(); final AtomicReference<Failure[]> conflicts = new AtomicReference<Failure[]>(); final boolean noAutoResolve = flags.contains(CheckinFlags.NO_AUTO_RESOLVE); final CheckinResult result; try { /* * If changes was null when this method was called, serverItems * will be null here, which causes the server to check in all * workspace changes. */ result = getClient().getWebServiceLayer().checkIn(getName(), getOwnerName(), serverItems, changeset, makeCheckinNotificationInfo(associatedWorkItems), flags, null, conflicts, failures, false, 0, client.mergeWithDefaultItemPropertyFilters(null)); } catch (final ActionDeniedBySubscriberException e) { if (e.getSubscriberType().equals(BUILD_CHECKIN_SUBSCRIBER) && e.getStatusCode() == 1) { /* * For ease of use, convert the * ActionDeniedBySubscriberException into a stronger type, * GatedCheckinException. This exception has helper * properties and is typed in a way that customers expect. * It is still an ActionDeniedBySubscriberException. */ throw new GatedCheckinException(e); } else { /* * Some other subscriber has denied the decision point. * Throw the ActionDeniedBySubscriberException verbatim. */ throw e; } } monitor.worked(10); changeset.setChangesetID(result.getChangeset()); // Report any failures. reportCheckinConflictsAndThrow(result, conflicts.get(), failures.get(), noAutoResolve); /* * When the SetFileTimeToCheckin workspace option is set, then the * full checkin manifest is returned to the client in the form of * GetOperations, even in a server workspace. (In a server * workspace, the local version updates are still performed by the * server at the end of the CheckIn call.) We use this manifest to * set the check-in date on each item in the changeset, even * implicitly included missing parents and affected items of * recursive changes. */ final TaskMonitor setFileTimeMonitor = monitor.newSubTaskMonitor(5); try { if (getOptions().contains(WorkspaceOptions.SET_FILE_TO_CHECKIN)) { final GetOperation[] updates = result.getLocalVersionUpdates(); if (updates != null && updates.length > 0) { setFileTimeMonitor.begin(Messages.getString("Workspace.SettingFileTime"), updates.length); //$NON-NLS-1$ for (final GetOperation getOp : updates) { if (ItemType.FILE == getOp.getItemType() && null != getOp.getTargetLocalItem() && new File(getOp.getTargetLocalItem()).exists()) { setFileTimeMonitor.setCurrentWorkDescription(getOp.getTargetLocalItem()); try { final FileSystemAttributes attributes = FileSystemUtils.getInstance() .getAttributes(getOp.getTargetLocalItem()); boolean restoreReadOnly = false; /* * Temporarily remove the read-only flag so * we can modify the time (Windows requires * this). */ if (attributes.isReadOnly()) { attributes.setReadOnly(false); FileSystemUtils.getInstance().setAttributes(getOp.getTargetLocalItem(), attributes); restoreReadOnly = true; } new File(getOp.getTargetLocalItem()) .setLastModified(result.getCreationDate().getTimeInMillis()); if (restoreReadOnly) { attributes.setReadOnly(true); FileSystemUtils.getInstance().setAttributes(getOp.getTargetLocalItem(), attributes); } } catch (final Exception e) { client.getEventEngine().fireNonFatalError( new NonFatalErrorEvent(EventSource.newFromHere(), this, e)); } } } } } } finally { setFileTimeMonitor.done(); } /* * If this is a server workspace, set files read-only. */ final TaskMonitor makeReadOnlyMonitor = monitor.newSubTaskMonitor(5); try { if (changes != null && getLocation() == WorkspaceLocation.SERVER) { makeReadOnlyMonitor.begin(Messages.getString("Workspace.SettingReadOnly"), changes.length); //$NON-NLS-1$ for (final PendingChange change : changes) { if (change.getChangeType().contains(ChangeType.EDIT) && change.getLocalItem() != null && new File(change.getLocalItem()).exists()) { makeReadOnlyMonitor.setCurrentWorkDescription(change.getLocalItem()); try { final FileSystemAttributes attributes = FileSystemUtils.getInstance() .getAttributes(change.getLocalItem()); if (!attributes.isSymbolicLink() && !attributes.isDirectory()) { attributes.setReadOnly(true); FileSystemUtils.getInstance().setAttributes(change.getLocalItem(), attributes); } } catch (final Exception e) { client.getEventEngine().fireNonFatalError( new NonFatalErrorEvent(EventSource.newFromHere(), this, e)); } } else { // Skipping this one. makeReadOnlyMonitor.setCurrentWorkDescription(""); //$NON-NLS-1$ } makeReadOnlyMonitor.worked(1); } } } finally { makeReadOnlyMonitor.done(); } monitor.setCurrentWorkDescription(Messages.getString("Workspace.NotifyingListeners")); //$NON-NLS-1$ /* * Determine which pending changes were committed and which were * undone. Preserve the sorted order in the sublists. */ PendingChange[] committedChangesArray = new PendingChange[0]; PendingChange[] undoneChangesArray = new PendingChange[0]; if (changes != null && changes.length > 0) { final Set<String> undoneServerItems = new TreeSet<String>(ServerPath.TOP_DOWN_COMPARATOR); for (final String undoneServerItem : result.getUndoneServerItems()) { undoneServerItems.add(undoneServerItem); } final List<PendingChange> undonePendingChanges = new ArrayList<PendingChange>( undoneServerItems.size()); final List<PendingChange> committedPendingChanges = new ArrayList<PendingChange>(); for (final PendingChange change : changes) { if (undoneServerItems.contains(change.getServerItem())) { undonePendingChanges.add(change); } else { committedPendingChanges.add(change); } } committedChangesArray = committedPendingChanges .toArray(new PendingChange[committedPendingChanges.size()]); undoneChangesArray = undonePendingChanges.toArray(new PendingChange[undonePendingChanges.size()]); } // Notify the user that the checkin iCheckinEvents complete. client.getEventEngine().fireCheckin(new CheckinEvent(EventSource.newFromHere(), this, result.getChangeset(), committedChangesArray, undoneChangesArray)); Workstation.getCurrent(getClient().getConnection().getPersistenceStoreProvider()) .notifyForWorkspace(this, Notification.VERSION_CONTROL_PENDING_CHANGES_CHANGED); monitor.worked(1); final int cset = changeset.getChangesetID(); TaskMonitorService.pushTaskMonitor(monitor.newSubTaskMonitor(4)); try { /* * Only update work items if we have a valid (non-0) changeset. * Changeset 0 indicates all the pending changes were undone on * the server. */ if (cset != 0) { updateWorkItems(associatedWorkItems, cset, comment); } } finally { TaskMonitorService.popTaskMonitor(true); } // Remove any saved attempted checkin info. setLastSavedCheckin(buildEmptyLastSavedCheckin()); success = true; return cset; } catch (final CanceledException e) { // Fire as non-fatal client.getEventEngine().fireNonFatalError(new NonFatalErrorEvent(EventSource.newFromHere(), this, new CoreCancelException(Messages.getString("Workspace.CheckinCancelled")))); //$NON-NLS-1$ return 0; } catch (final CoreCancelException e) { // Convert to CanceledException and fire as non-fatal client.getEventEngine().fireNonFatalError(new NonFatalErrorEvent(EventSource.newFromHere(), this, new CanceledException(Messages.getString("Workspace.CheckinCancelled")))); //$NON-NLS-1$ return 0; } finally { /* * If the checkin didn't succeed, save the info for the next * attempt. success will be false for expected things like gated * checkin and cancelation exceptions, and also for unexpected * exceptions. */ if (!success) { updateLastSavedCheckin(comment, checkinNote, associatedWorkItems, policyOverrideInfo); } monitor.done(); } }
From source file:com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace.java
/** * Pend these changes for this workspace on the server. * * @param requests/* w w w . java 2 s . c om*/ * the requested changes to pend (must not be <code>null</code>) * @param getOptions * options that affect how files on disk are treated during * processing (must not be <code>null</code>) * @param pendOptions * options that affect how items are pended (must not be * <code>null</code>) * @param itemPropertyFilters * a list of versioned item properties to return with each get * operation (may be <code>null</code>) * @return the number of changes that were successfully processed by the * server. */ private int pendChanges(final ChangeRequest[] requests, final GetOptions getOptions, final PendChangesOptions pendOptions, String[] itemPropertyFilters) { Check.notNull(requests, "requests"); //$NON-NLS-1$ Check.notNull(getOptions, "getOptions"); //$NON-NLS-1$ Check.notNull(pendOptions, "pendOptions"); //$NON-NLS-1$ // Using web service directly so merge filters configured on client itemPropertyFilters = client.mergeWithDefaultItemPropertyFilters(itemPropertyFilters); client.getEventEngine() .fireOperationStarted(new PendOperationStartedEvent(EventSource.newFromHere(), this, requests)); if (getClient().getServiceLevel().getValue() < WebServiceLevel.TFS_2012.getValue()) { if (hasPropertyChange(requests)) { client.getEventEngine().fireNonFatalError(new NonFatalErrorEvent(EventSource.newFromHere(), this, new VersionControlException(Messages.getString("Workspace.PropertyNotSupportedText")))); //$NON-NLS-1$ } } int ret = 0; try { SupportedFeatures features = SupportedFeatures.ALL; /* * If the get operation "Force Checkout Local Version" is set, we do * not advertise to the server that we support get latest on * checkout. Presumably, there may be a state where the server * wishes to update us to the local version and this explicitly * stops that. */ if (pendOptions.contains(PendChangesOptions.FORCE_CHECK_OUT_LOCAL_VERSION)) { features = features.remove(SupportedFeatures.GET_LATEST_ON_CHECKOUT); } final AtomicReference<Failure[]> failures = new AtomicReference<Failure[]>(); final AtomicBoolean onlineOperation = new AtomicBoolean(); final AtomicReference<ChangePendedFlags> changePendedFlags = new AtomicReference<ChangePendedFlags>(); final GetOperation[] operations = client.getWebServiceLayer().pendChanges(getName(), getOwnerName(), requests, pendOptions, features, failures, itemPropertyFilters, null, true, onlineOperation, changePendedFlags); // Get any required files. if (operations.length > 0) { /* * The TFS server (as of TFS 2013 QU1) provides in the response * only properties saved in the server's database, i.e. already * checked in. Thus, to process the executable bit and symlinks * using properties mechanism correctly in the client file * system, we have to merge properties received in the response * with those submitted in the change request. * * Note that for the local workspaces it's already done in the * LocalDataAccessLayer class. */ if (WorkspaceLocation.SERVER == this.getLocation() && getClient().getServiceLevel().getValue() >= WebServiceLevel.TFS_2012.getValue()) { for (final ChangeRequest request : requests) { final PropertyValue[] requestProperties = request.getProperties(); if (requestProperties != null) { final GetOperation operation = findMatchingOperation(operations, request); if (operation != null) { final PropertyValue[] operationProperties = operation.getPropertyValues(); if (operationProperties != null) { operation.setPropertyValues(PropertyUtils .mergePendingValues(operationProperties, requestProperties)); } } } } } final GetEngine getEngine = new GetEngine(client); getEngine.processGetOperations(this, ProcessType.PEND, requests[0].getRequestType(), new GetOperation[][] { operations }, getOptions, false, onlineOperation.get(), changePendedFlags.get()); // Return the number of operations that were successful. ret = operations.length; } if (changePendedFlags.get().contains(ChangePendedFlags.WORKING_FOLDER_MAPPINGS_UPDATED)) { invalidateMappings(); } /* * If it was requested by the caller, strip out any Failure objects * from the failure set which are of type ItemNotFoundException. */ if (failures.get() != null && failures.get().length > 0 && pendOptions.contains(PendChangesOptions.SUPPRESS_ITEM_NOT_FOUND_FAILURES)) { final List<Failure> otherFailures = new ArrayList<Failure>(); for (final Failure f : failures.get()) { if (f.getCode() == null || !f.getCode().equals(FailureCodes.ITEM_EXISTS_EXCEPTION)) { otherFailures.add(f); } } failures.set(otherFailures.toArray(new Failure[otherFailures.size()])); } client.reportFailures(this, failures.get()); } finally { client.getEventEngine().fireOperationCompleted( new PendOperationCompletedEvent(EventSource.newFromHere(), this, requests)); Workstation.getCurrent(getClient().getConnection().getPersistenceStoreProvider()) .notifyForWorkspace(this, Notification.VERSION_CONTROL_PENDING_CHANGES_CHANGED); } return ret; }
From source file:de.schildbach.pte.AbstractEfaProvider.java
private QueryDeparturesResult xsltDepartureMonitorRequest(final String stationId, final @Nullable Date time, final int maxDepartures, final boolean equivs) throws IOException { final HttpUrl.Builder url = departureMonitorEndpoint.newBuilder(); appendXsltDepartureMonitorRequestParameters(url, stationId, time, maxDepartures, equivs); final AtomicReference<QueryDeparturesResult> result = new AtomicReference<>(); final HttpClient.Callback callback = new HttpClient.Callback() { @Override// w ww . ja v a 2s. c o m public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException { try { final XmlPullParser pp = parserFactory.newPullParser(); pp.setInput(body.byteStream(), null); // Read encoding from XML declaration final ResultHeader header = enterItdRequest(pp); final QueryDeparturesResult r = new QueryDeparturesResult(header); XmlPullUtil.enter(pp, "itdDepartureMonitorRequest"); XmlPullUtil.optSkipMultiple(pp, "itdMessage"); final String nameState = processItdOdv(pp, "dm", new ProcessItdOdvCallback() { @Override public void location(final String nameState, final Location location, final int matchQuality) { if (location.type == LocationType.STATION) if (findStationDepartures(r.stationDepartures, location.id) == null) r.stationDepartures.add(new StationDepartures(location, new LinkedList<Departure>(), new LinkedList<LineDestination>())); } }); if ("notidentified".equals(nameState) || "list".equals(nameState)) { result.set(new QueryDeparturesResult(header, QueryDeparturesResult.Status.INVALID_STATION)); return; } XmlPullUtil.optSkip(pp, "itdDateTime"); XmlPullUtil.optSkip(pp, "itdDMDateTime"); XmlPullUtil.optSkip(pp, "itdDateRange"); XmlPullUtil.optSkip(pp, "itdTripOptions"); XmlPullUtil.optSkip(pp, "itdMessage"); if (XmlPullUtil.test(pp, "itdServingLines")) { if (!pp.isEmptyElementTag()) { XmlPullUtil.enter(pp, "itdServingLines"); while (XmlPullUtil.test(pp, "itdServingLine")) { final String assignedStopId = XmlPullUtil.optAttr(pp, "assignedStopID", null); final LineDestinationAndCancelled lineDestinationAndCancelled = processItdServingLine( pp); final LineDestination lineDestination = new LineDestination( lineDestinationAndCancelled.line, lineDestinationAndCancelled.destination); StationDepartures assignedStationDepartures; if (assignedStopId == null) assignedStationDepartures = r.stationDepartures.get(0); else assignedStationDepartures = findStationDepartures(r.stationDepartures, assignedStopId); if (assignedStationDepartures == null) assignedStationDepartures = new StationDepartures( new Location(LocationType.STATION, assignedStopId), new LinkedList<Departure>(), new LinkedList<LineDestination>()); final List<LineDestination> assignedStationDeparturesLines = checkNotNull( assignedStationDepartures.lines); if (!assignedStationDeparturesLines.contains(lineDestination)) assignedStationDeparturesLines.add(lineDestination); } XmlPullUtil.skipExit(pp, "itdServingLines"); } else { XmlPullUtil.next(pp); } } else { result.set(new QueryDeparturesResult(header, QueryDeparturesResult.Status.INVALID_STATION)); return; } XmlPullUtil.require(pp, "itdDepartureList"); if (XmlPullUtil.optEnter(pp, "itdDepartureList")) { final Calendar plannedDepartureTime = new GregorianCalendar(timeZone); final Calendar predictedDepartureTime = new GregorianCalendar(timeZone); while (XmlPullUtil.test(pp, "itdDeparture")) { final String assignedStopId = XmlPullUtil.attr(pp, "stopID"); StationDepartures assignedStationDepartures = findStationDepartures(r.stationDepartures, assignedStopId); if (assignedStationDepartures == null) { final Point coord = processCoordAttr(pp); // final String name = normalizeLocationName(XmlPullUtil.attr(pp, "nameWO")); assignedStationDepartures = new StationDepartures( new Location(LocationType.STATION, assignedStopId, coord), new LinkedList<Departure>(), new LinkedList<LineDestination>()); } final Position position = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null)); XmlPullUtil.enter(pp, "itdDeparture"); XmlPullUtil.require(pp, "itdDateTime"); plannedDepartureTime.clear(); processItdDateTime(pp, plannedDepartureTime); predictedDepartureTime.clear(); if (XmlPullUtil.test(pp, "itdRTDateTime")) processItdDateTime(pp, predictedDepartureTime); XmlPullUtil.optSkip(pp, "itdFrequencyInfo"); XmlPullUtil.require(pp, "itdServingLine"); final boolean isRealtime = XmlPullUtil.attr(pp, "realtime").equals("1"); final LineDestinationAndCancelled lineDestinationAndCancelled = processItdServingLine( pp); if (isRealtime && !predictedDepartureTime.isSet(Calendar.HOUR_OF_DAY)) predictedDepartureTime.setTimeInMillis(plannedDepartureTime.getTimeInMillis()); XmlPullUtil.skipExit(pp, "itdDeparture"); if (!lineDestinationAndCancelled.cancelled) { final Departure departure = new Departure(plannedDepartureTime.getTime(), predictedDepartureTime.isSet(Calendar.HOUR_OF_DAY) ? predictedDepartureTime.getTime() : null, lineDestinationAndCancelled.line, position, lineDestinationAndCancelled.destination, null, null); assignedStationDepartures.departures.add(departure); } } XmlPullUtil.skipExit(pp, "itdDepartureList"); } result.set(r); } catch (final XmlPullParserException x) { throw new ParserException("cannot parse xml: " + bodyPeek, x); } } }; if (httpPost) httpClient.getInputStream(callback, url.build(), url.build().encodedQuery(), "application/x-www-form-urlencoded", httpReferer); else httpClient.getInputStream(callback, url.build(), httpReferer); return result.get(); }
From source file:de.schildbach.pte.AbstractHafasLegacyProvider.java
protected final QueryDeparturesResult xmlStationBoard(final HttpUrl url, final String stationId) throws IOException { final String normalizedStationId = normalizeStationId(stationId); final AtomicReference<QueryDeparturesResult> result = new AtomicReference<>(); httpClient.getInputStream(new HttpClient.Callback() { @Override//from w ww. ja v a 2 s. com public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException { StringReplaceReader reader = null; String firstChars = null; // work around unparsable XML reader = new StringReplaceReader(body.charStream(), " & ", " & "); reader.replace("<b>", " "); reader.replace("</b>", " "); reader.replace("<u>", " "); reader.replace("</u>", " "); reader.replace("<i>", " "); reader.replace("</i>", " "); reader.replace("<br />", " "); reader.replace(" ->", " →"); // right arrow reader.replace(" <-", " ←"); // left arrow reader.replace(" <> ", " ↔ "); // left-right arrow addCustomReplaces(reader); try { final XmlPullParserFactory factory = XmlPullParserFactory .newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null); final XmlPullParser pp = factory.newPullParser(); pp.setInput(reader); pp.nextTag(); final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT); final QueryDeparturesResult r = new QueryDeparturesResult(header); if (XmlPullUtil.test(pp, "Err")) { final String code = XmlPullUtil.attr(pp, "code"); final String text = XmlPullUtil.attr(pp, "text"); if (code.equals("H730")) { result.set(new QueryDeparturesResult(header, QueryDeparturesResult.Status.INVALID_STATION)); return; } if (code.equals("H890")) { r.stationDepartures.add( new StationDepartures(new Location(LocationType.STATION, normalizedStationId), Collections.<Departure>emptyList(), null)); result.set(r); return; } throw new IllegalArgumentException("unknown error " + code + ", " + text); } String[] stationPlaceAndName = null; if (stationBoardHasStationTable) XmlPullUtil.enter(pp, "StationTable"); else checkState(!XmlPullUtil.test(pp, "StationTable")); if (stationBoardHasLocation) { XmlPullUtil.require(pp, "St"); final String evaId = XmlPullUtil.attr(pp, "evaId"); if (evaId != null) { if (!evaId.equals(normalizedStationId)) throw new IllegalStateException( "stationId: " + normalizedStationId + ", evaId: " + evaId); final String name = XmlPullUtil.attr(pp, "name"); if (name != null) stationPlaceAndName = splitStationName(name.trim()); } XmlPullUtil.requireSkip(pp, "St"); } else { checkState(!XmlPullUtil.test(pp, "St")); } while (XmlPullUtil.test(pp, "Journey")) { final String fpTime = XmlPullUtil.attr(pp, "fpTime"); final String fpDate = XmlPullUtil.attr(pp, "fpDate"); final String delay = XmlPullUtil.attr(pp, "delay"); final String eDelay = XmlPullUtil.optAttr(pp, "e_delay", null); final String platform = XmlPullUtil.optAttr(pp, "platform", null); // TODO newpl final String targetLoc = XmlPullUtil.optAttr(pp, "targetLoc", null); // TODO hafasname final String dirnr = XmlPullUtil.optAttr(pp, "dirnr", null); final String prod = XmlPullUtil.attr(pp, "prod"); final String classStr = XmlPullUtil.optAttr(pp, "class", null); final String dir = XmlPullUtil.optAttr(pp, "dir", null); final String capacityStr = XmlPullUtil.optAttr(pp, "capacity", null); final String depStation = XmlPullUtil.optAttr(pp, "depStation", null); final String delayReason = XmlPullUtil.optAttr(pp, "delayReason", null); // TODO is_reachable // TODO disableTrainInfo // TODO lineFG/lineBG (ZVV) final String administration = normalizeLineAdministration( XmlPullUtil.optAttr(pp, "administration", null)); if (!"cancel".equals(delay) && !"cancel".equals(eDelay)) { final Calendar plannedTime = new GregorianCalendar(timeZone); plannedTime.clear(); parseXmlStationBoardDate(plannedTime, fpDate); parseXmlStationBoardTime(plannedTime, fpTime); final Calendar predictedTime; if (eDelay != null) { predictedTime = new GregorianCalendar(timeZone); predictedTime.setTimeInMillis(plannedTime.getTimeInMillis()); predictedTime.add(Calendar.MINUTE, Integer.parseInt(eDelay)); } else if (delay != null) { final Matcher m = P_XML_STATION_BOARD_DELAY.matcher(delay); if (m.matches()) { if (m.group(1) != null) { predictedTime = new GregorianCalendar(timeZone); predictedTime.setTimeInMillis(plannedTime.getTimeInMillis()); predictedTime.add(Calendar.MINUTE, Integer.parseInt(m.group(1))); } else { predictedTime = null; } } else { throw new RuntimeException("cannot parse delay: '" + delay + "'"); } } else { predictedTime = null; } final Position position = parsePosition(ParserUtils.resolveEntities(platform)); final String destinationName; if (dir != null) destinationName = dir.trim(); else if (targetLoc != null) destinationName = targetLoc.trim(); else destinationName = null; final Location destination; if (dirnr != null) { final String[] destinationPlaceAndName = splitStationName(destinationName); destination = new Location(LocationType.STATION, dirnr, destinationPlaceAndName[0], destinationPlaceAndName[1]); } else { destination = new Location(LocationType.ANY, null, null, destinationName); } final Line prodLine = parseLineAndType(prod); final Line line; if (classStr != null) { final Product product = intToProduct(Integer.parseInt(classStr)); if (product == null) throw new IllegalArgumentException(); // could check for type consistency here final Set<Attr> attrs = prodLine.attrs; if (attrs != null) line = newLine(administration, product, prodLine.label, null, attrs.toArray(new Line.Attr[0])); else line = newLine(administration, product, prodLine.label, null); } else { final Set<Attr> attrs = prodLine.attrs; if (attrs != null) line = newLine(administration, prodLine.product, prodLine.label, null, attrs.toArray(new Line.Attr[0])); else line = newLine(administration, prodLine.product, prodLine.label, null); } final int[] capacity; if (capacityStr != null && !"0|0".equals(capacityStr)) { final String[] capacityParts = capacityStr.split("\\|"); capacity = new int[] { Integer.parseInt(capacityParts[0]), Integer.parseInt(capacityParts[1]) }; } else { capacity = null; } final String message; if (delayReason != null) { final String msg = delayReason.trim(); message = msg.length() > 0 ? msg : null; } else { message = null; } final Departure departure = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line, position, destination, capacity, message); final Location location; if (!stationBoardCanDoEquivs || depStation == null) { location = new Location(LocationType.STATION, normalizedStationId, stationPlaceAndName != null ? stationPlaceAndName[0] : null, stationPlaceAndName != null ? stationPlaceAndName[1] : null); } else { final String[] depPlaceAndName = splitStationName(depStation); location = new Location(LocationType.STATION, null, depPlaceAndName[0], depPlaceAndName[1]); } StationDepartures stationDepartures = findStationDepartures(r.stationDepartures, location); if (stationDepartures == null) { stationDepartures = new StationDepartures(location, new ArrayList<Departure>(8), null); r.stationDepartures.add(stationDepartures); } stationDepartures.departures.add(departure); } XmlPullUtil.requireSkip(pp, "Journey"); } if (stationBoardHasStationTable) XmlPullUtil.exit(pp, "StationTable"); XmlPullUtil.requireEndDocument(pp); // sort departures for (final StationDepartures stationDepartures : r.stationDepartures) Collections.sort(stationDepartures.departures, Departure.TIME_COMPARATOR); result.set(r); } catch (final XmlPullParserException x) { throw new ParserException("cannot parse xml: " + firstChars, x); } } }, url); return result.get(); }
From source file:de.schildbach.pte.AbstractHafasLegacyProvider.java
private QueryTripsResult queryTripsXml(final Context previousContext, final boolean later, final CharSequence conReq, final Location from, final @Nullable Location via, final Location to) throws IOException { final String request = wrapReqC(conReq, null); final HttpUrl endpoint = extXmlEndpoint != null ? extXmlEndpoint : queryEndpoint.newBuilder().addPathSegment(apiLanguage).build(); final AtomicReference<QueryTripsResult> result = new AtomicReference<>(); httpClient.getInputStream(new HttpClient.Callback() { @Override//www. j a v a 2 s .c o m public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException { try { final XmlPullParserFactory factory = XmlPullParserFactory .newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null); final XmlPullParser pp = factory.newPullParser(); pp.setInput(body.charStream()); XmlPullUtil.require(pp, "ResC"); final String product = XmlPullUtil.attr(pp, "prod").split(" ")[0]; final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT, product, null, 0, null); XmlPullUtil.enter(pp, "ResC"); if (XmlPullUtil.test(pp, "Err")) { final String code = XmlPullUtil.attr(pp, "code"); if (code.equals("I3")) { result.set(new QueryTripsResult(header, QueryTripsResult.Status.INVALID_DATE)); return; } if (code.equals("F1")) { result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } throw new IllegalStateException("error " + code + " " + XmlPullUtil.attr(pp, "text")); } XmlPullUtil.enter(pp, "ConRes"); if (XmlPullUtil.test(pp, "Err")) { final String code = XmlPullUtil.attr(pp, "code"); log.debug("Hafas error: {}", code); if (code.equals("K9260")) { // Unknown departure station result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNKNOWN_FROM)); return; } if (code.equals("K9280")) { // Unknown intermediate station result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNKNOWN_VIA)); return; } if (code.equals("K9300")) { // Unknown arrival station result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNKNOWN_TO)); return; } if (code.equals("K9360")) { // Date outside of the timetable period result.set(new QueryTripsResult(header, QueryTripsResult.Status.INVALID_DATE)); return; } if (code.equals("K9380")) { // Dep./Arr./Intermed. or equivalent station defined more than once result.set(new QueryTripsResult(header, QueryTripsResult.Status.TOO_CLOSE)); return; } if (code.equals("K895")) { // Departure/Arrival are too near result.set(new QueryTripsResult(header, QueryTripsResult.Status.TOO_CLOSE)); return; } if (code.equals("K9220")) { // Nearby to the given address stations could not be found result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNRESOLVABLE_ADDRESS)); return; } if (code.equals("K9240")) { // Internal error result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } if (code.equals("K890")) { // No connections found result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } if (code.equals("K891")) { // No route found (try entering an intermediate station) result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } if (code.equals("K899")) { // An error occurred result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } if (code.equals("K1:890")) { // Unsuccessful or incomplete search (direction: forward) result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } if (code.equals("K2:890")) { // Unsuccessful or incomplete search (direction: backward) result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } throw new IllegalStateException("error " + code + " " + XmlPullUtil.attr(pp, "text")); } // H9380 Dep./Arr./Intermed. or equivalent stations defined more than once // H9360 Error in data field // H9320 The input is incorrect or incomplete // H9300 Unknown arrival station // H9280 Unknown intermediate station // H9260 Unknown departure station // H9250 Part inquiry interrupted // H9240 Unsuccessful search // H9230 An internal error occurred // H9220 Nearby to the given address stations could not be found // H900 Unsuccessful or incomplete search (timetable change) // H892 Inquiry too complex (try entering less intermediate stations) // H891 No route found (try entering an intermediate station) // H890 Unsuccessful search. // H500 Because of too many trains the connection is not complete // H460 One or more stops are passed through multiple times. // H455 Prolonged stop // H410 Display may be incomplete due to change of timetable // H390 Departure/Arrival replaced by an equivalent station // H895 Departure/Arrival are too near // H899 Unsuccessful or incomplete search (timetable change final String c = XmlPullUtil.optValueTag(pp, "ConResCtxt", null); final Context context; if (previousContext == null) context = new Context(c, c, 0); else if (later) context = new Context(c, previousContext.earlierContext, previousContext.sequence + 1); else context = new Context(previousContext.laterContext, c, previousContext.sequence + 1); XmlPullUtil.enter(pp, "ConnectionList"); final List<Trip> trips = new ArrayList<>(); while (XmlPullUtil.test(pp, "Connection")) { final String id = context.sequence + "/" + XmlPullUtil.attr(pp, "id"); XmlPullUtil.enter(pp, "Connection"); while (pp.getName().equals("RtStateList")) XmlPullUtil.next(pp); XmlPullUtil.enter(pp, "Overview"); final Calendar currentDate = new GregorianCalendar(timeZone); currentDate.clear(); parseDate(currentDate, XmlPullUtil.valueTag(pp, "Date")); XmlPullUtil.enter(pp, "Departure"); XmlPullUtil.enter(pp, "BasicStop"); while (pp.getName().equals("StAttrList")) XmlPullUtil.next(pp); final Location departureLocation = parseLocation(pp); XmlPullUtil.enter(pp, "Dep"); XmlPullUtil.skipExit(pp, "Dep"); final int[] capacity; if (XmlPullUtil.test(pp, "StopPrognosis")) { XmlPullUtil.enter(pp, "StopPrognosis"); XmlPullUtil.optSkip(pp, "Arr"); XmlPullUtil.optSkip(pp, "Dep"); XmlPullUtil.enter(pp, "Status"); XmlPullUtil.skipExit(pp, "Status"); final int capacity1st = Integer .parseInt(XmlPullUtil.optValueTag(pp, "Capacity1st", "0")); final int capacity2nd = Integer .parseInt(XmlPullUtil.optValueTag(pp, "Capacity2nd", "0")); if (capacity1st > 0 || capacity2nd > 0) capacity = new int[] { capacity1st, capacity2nd }; else capacity = null; XmlPullUtil.skipExit(pp, "StopPrognosis"); } else { capacity = null; } XmlPullUtil.skipExit(pp, "BasicStop"); XmlPullUtil.skipExit(pp, "Departure"); XmlPullUtil.enter(pp, "Arrival"); XmlPullUtil.enter(pp, "BasicStop"); while (pp.getName().equals("StAttrList")) XmlPullUtil.next(pp); final Location arrivalLocation = parseLocation(pp); XmlPullUtil.skipExit(pp, "BasicStop"); XmlPullUtil.skipExit(pp, "Arrival"); final int numTransfers = Integer.parseInt(XmlPullUtil.valueTag(pp, "Transfers")); XmlPullUtil.skipExit(pp, "Overview"); final List<Trip.Leg> legs = new ArrayList<>(4); XmlPullUtil.enter(pp, "ConSectionList"); final Calendar time = new GregorianCalendar(timeZone); while (XmlPullUtil.test(pp, "ConSection")) { XmlPullUtil.enter(pp, "ConSection"); // departure XmlPullUtil.enter(pp, "Departure"); XmlPullUtil.enter(pp, "BasicStop"); while (pp.getName().equals("StAttrList")) XmlPullUtil.next(pp); final Location sectionDepartureLocation = parseLocation(pp); XmlPullUtil.optSkip(pp, "Arr"); XmlPullUtil.enter(pp, "Dep"); time.setTimeInMillis(currentDate.getTimeInMillis()); parseTime(time, XmlPullUtil.valueTag(pp, "Time")); final Date departureTime = time.getTime(); final Position departurePos = parsePlatform(pp); XmlPullUtil.skipExit(pp, "Dep"); XmlPullUtil.skipExit(pp, "BasicStop"); XmlPullUtil.skipExit(pp, "Departure"); // journey final Line line; Location destination = null; List<Stop> intermediateStops = null; final String tag = pp.getName(); if (tag.equals("Journey")) { XmlPullUtil.enter(pp, "Journey"); while (pp.getName().equals("JHandle")) XmlPullUtil.next(pp); XmlPullUtil.enter(pp, "JourneyAttributeList"); boolean wheelchairAccess = false; String name = null; String category = null; String shortCategory = null; while (XmlPullUtil.test(pp, "JourneyAttribute")) { XmlPullUtil.enter(pp, "JourneyAttribute"); XmlPullUtil.require(pp, "Attribute"); final String attrName = XmlPullUtil.attr(pp, "type"); final String code = XmlPullUtil.optAttr(pp, "code", null); XmlPullUtil.enter(pp, "Attribute"); final Map<String, String> attributeVariants = parseAttributeVariants(pp); XmlPullUtil.skipExit(pp, "Attribute"); XmlPullUtil.skipExit(pp, "JourneyAttribute"); if ("bf".equals(code)) { wheelchairAccess = true; } else if ("NAME".equals(attrName)) { name = attributeVariants.get("NORMAL"); } else if ("CATEGORY".equals(attrName)) { shortCategory = attributeVariants.get("SHORT"); category = attributeVariants.get("NORMAL"); // longCategory = attributeVariants.get("LONG"); } else if ("DIRECTION".equals(attrName)) { final String[] destinationPlaceAndName = splitStationName( attributeVariants.get("NORMAL")); destination = new Location(LocationType.ANY, null, destinationPlaceAndName[0], destinationPlaceAndName[1]); } } XmlPullUtil.skipExit(pp, "JourneyAttributeList"); if (XmlPullUtil.test(pp, "PassList")) { intermediateStops = new LinkedList<>(); XmlPullUtil.enter(pp, "PassList"); while (XmlPullUtil.test(pp, "BasicStop")) { XmlPullUtil.enter(pp, "BasicStop"); while (XmlPullUtil.test(pp, "StAttrList")) XmlPullUtil.next(pp); final Location location = parseLocation(pp); if (location.id != sectionDepartureLocation.id) { Date stopArrivalTime = null; Date stopDepartureTime = null; Position stopArrivalPosition = null; Position stopDeparturePosition = null; if (XmlPullUtil.test(pp, "Arr")) { XmlPullUtil.enter(pp, "Arr"); time.setTimeInMillis(currentDate.getTimeInMillis()); parseTime(time, XmlPullUtil.valueTag(pp, "Time")); stopArrivalTime = time.getTime(); stopArrivalPosition = parsePlatform(pp); XmlPullUtil.skipExit(pp, "Arr"); } if (XmlPullUtil.test(pp, "Dep")) { XmlPullUtil.enter(pp, "Dep"); time.setTimeInMillis(currentDate.getTimeInMillis()); parseTime(time, XmlPullUtil.valueTag(pp, "Time")); stopDepartureTime = time.getTime(); stopDeparturePosition = parsePlatform(pp); XmlPullUtil.skipExit(pp, "Dep"); } intermediateStops.add(new Stop(location, stopArrivalTime, stopArrivalPosition, stopDepartureTime, stopDeparturePosition)); } XmlPullUtil.skipExit(pp, "BasicStop"); } XmlPullUtil.skipExit(pp, "PassList"); } XmlPullUtil.skipExit(pp, "Journey"); if (category == null) category = shortCategory; line = parseLine(category, name, wheelchairAccess); } else if (tag.equals("Walk") || tag.equals("Transfer") || tag.equals("GisRoute")) { XmlPullUtil.enter(pp); XmlPullUtil.enter(pp, "Duration"); XmlPullUtil.skipExit(pp, "Duration"); XmlPullUtil.skipExit(pp); line = null; } else { throw new IllegalStateException("cannot handle: " + pp.getName()); } // polyline final List<Point> path; if (XmlPullUtil.test(pp, "Polyline")) { path = new LinkedList<>(); XmlPullUtil.enter(pp, "Polyline"); while (XmlPullUtil.test(pp, "Point")) { final int x = XmlPullUtil.intAttr(pp, "x"); final int y = XmlPullUtil.intAttr(pp, "y"); path.add(new Point(y, x)); XmlPullUtil.next(pp); } XmlPullUtil.skipExit(pp, "Polyline"); } else { path = null; } // arrival XmlPullUtil.enter(pp, "Arrival"); XmlPullUtil.enter(pp, "BasicStop"); while (pp.getName().equals("StAttrList")) XmlPullUtil.next(pp); final Location sectionArrivalLocation = parseLocation(pp); XmlPullUtil.enter(pp, "Arr"); time.setTimeInMillis(currentDate.getTimeInMillis()); parseTime(time, XmlPullUtil.valueTag(pp, "Time")); final Date arrivalTime = time.getTime(); final Position arrivalPos = parsePlatform(pp); XmlPullUtil.skipExit(pp, "Arr"); XmlPullUtil.skipExit(pp, "BasicStop"); XmlPullUtil.skipExit(pp, "Arrival"); // remove last intermediate if (intermediateStops != null) if (!intermediateStops.isEmpty()) if (!intermediateStops.get(intermediateStops.size() - 1).location .equals(sectionArrivalLocation)) intermediateStops.remove(intermediateStops.size() - 1); XmlPullUtil.skipExit(pp, "ConSection"); if (line != null) { final Stop departure = new Stop(sectionDepartureLocation, true, departureTime, null, departurePos, null); final Stop arrival = new Stop(sectionArrivalLocation, false, arrivalTime, null, arrivalPos, null); legs.add(new Trip.Public(line, destination, departure, arrival, intermediateStops, path, null)); } else { if (legs.size() > 0 && legs.get(legs.size() - 1) instanceof Trip.Individual) { final Trip.Individual lastIndividualLeg = (Trip.Individual) legs .remove(legs.size() - 1); legs.add(new Trip.Individual(Trip.Individual.Type.WALK, lastIndividualLeg.departure, lastIndividualLeg.departureTime, sectionArrivalLocation, arrivalTime, null, 0)); } else { legs.add( new Trip.Individual(Trip.Individual.Type.WALK, sectionDepartureLocation, departureTime, sectionArrivalLocation, arrivalTime, null, 0)); } } } XmlPullUtil.skipExit(pp, "ConSectionList"); XmlPullUtil.skipExit(pp, "Connection"); trips.add(new Trip(id, departureLocation, arrivalLocation, legs, null, capacity, numTransfers)); } XmlPullUtil.skipExit(pp, "ConnectionList"); result.set(new QueryTripsResult(header, null, from, via, to, context, trips)); } catch (final XmlPullParserException x) { throw new ParserException("cannot parse xml: " + bodyPeek, x); } } }, endpoint, request, "application/xml", null); return result.get(); }
From source file:de.schildbach.pte.AbstractHafasLegacyProvider.java
private QueryTripsResult queryTripsBinary(final HttpUrl url, final Location from, final @Nullable Location via, final Location to, final int expectedBufferSize) throws IOException { /*//from w w w. ja v a2 s .c o m * Many thanks to Malte Starostik and Robert, who helped a lot with analyzing this API! */ final AtomicReference<QueryTripsResult> result = new AtomicReference<>(); httpClient.getInputStream(new HttpClient.Callback() { @Override public void onSuccessful(final CharSequence bodyPeek, final ResponseBody body) throws IOException { final CustomBufferedInputStream bis = new CustomBufferedInputStream( new GZIPInputStream(body.byteStream())); // initialize input stream final LittleEndianDataInputStream is = new LittleEndianDataInputStream(bis); is.mark(expectedBufferSize); // quick check of status final int version = is.readShortReverse(); if (version != 6 && version != 5) throw new IllegalStateException("unknown version: " + version + ", first chars: " + bodyPeek); final ResultHeader header = new ResultHeader(network, SERVER_PRODUCT, Integer.toString(version), null, 0, null); // quick seek for pointers is.reset(); is.skipBytes(0x20); final int serviceDaysTablePtr = is.readIntReverse(); final int stringTablePtr = is.readIntReverse(); is.reset(); is.skipBytes(0x36); final int stationTablePtr = is.readIntReverse(); final int commentTablePtr = is.readIntReverse(); is.reset(); is.skipBytes(0x46); final int extensionHeaderPtr = is.readIntReverse(); // read strings final StringTable strings = new StringTable(is, stringTablePtr, serviceDaysTablePtr - stringTablePtr); is.reset(); is.skipBytes(extensionHeaderPtr); // read extension header final int extensionHeaderLength = is.readIntReverse(); if (extensionHeaderLength < 0x2c) throw new IllegalStateException("too short: " + extensionHeaderLength); is.skipBytes(12); final int errorCode = is.readShortReverse(); if (errorCode == 0) { // string encoding is.skipBytes(14); final Charset stringEncoding = Charset.forName(strings.read(is)); strings.setEncoding(stringEncoding); // read number of trips is.reset(); is.skipBytes(30); final int numTrips = is.readShortReverse(); if (numTrips == 0) { result.set(new QueryTripsResult(header, url.toString(), from, via, to, null, new LinkedList<Trip>())); return; } // read rest of header is.reset(); is.skipBytes(0x02); final Location resDeparture = location(is, strings); final Location resArrival = location(is, strings); is.skipBytes(10); final long resDate = date(is); /* final long resDate30 = */date(is); is.reset(); is.skipBytes(extensionHeaderPtr + 0x8); final int seqNr = is.readShortReverse(); if (seqNr == 0) throw new SessionExpiredException(); else if (seqNr < 0) throw new IllegalStateException("illegal sequence number: " + seqNr); final String requestId = strings.read(is); final int tripDetailsPtr = is.readIntReverse(); if (tripDetailsPtr == 0) throw new IllegalStateException("no connection details"); is.skipBytes(4); final int disruptionsPtr = is.readIntReverse(); is.skipBytes(10); final String ld = strings.read(is); final int attrsOffset = is.readIntReverse(); final int tripAttrsPtr; if (extensionHeaderLength >= 0x30) { if (extensionHeaderLength < 0x32) throw new IllegalArgumentException("too short: " + extensionHeaderLength); is.reset(); is.skipBytes(extensionHeaderPtr + 0x2c); tripAttrsPtr = is.readIntReverse(); } else { tripAttrsPtr = 0; } // determine stops offset is.reset(); is.skipBytes(tripDetailsPtr); final int tripDetailsVersion = is.readShortReverse(); if (tripDetailsVersion != 1) throw new IllegalStateException("unknown trip details version: " + tripDetailsVersion); is.skipBytes(0x02); final int tripDetailsIndexOffset = is.readShortReverse(); final int tripDetailsLegOffset = is.readShortReverse(); final int tripDetailsLegSize = is.readShortReverse(); final int stopsSize = is.readShortReverse(); final int stopsOffset = is.readShortReverse(); // read stations final StationTable stations = new StationTable(is, stationTablePtr, commentTablePtr - stationTablePtr, strings); // read comments final CommentTable comments = new CommentTable(is, commentTablePtr, tripDetailsPtr - commentTablePtr, strings); final List<Trip> trips = new ArrayList<>(numTrips); // read trips for (int iTrip = 0; iTrip < numTrips; iTrip++) { is.reset(); is.skipBytes(0x4a + iTrip * 12); final int serviceDaysTableOffset = is.readShortReverse(); final int legsOffset = is.readIntReverse(); final int numLegs = is.readShortReverse(); final int numChanges = is.readShortReverse(); /* final long duration = time(is, 0, 0); */is.readShortReverse(); is.reset(); is.skipBytes(serviceDaysTablePtr + serviceDaysTableOffset); /* final String serviceDaysText = */strings.read(is); final int serviceBitBase = is.readShortReverse(); final int serviceBitLength = is.readShortReverse(); int tripDayOffset = serviceBitBase * 8; for (int i = 0; i < serviceBitLength; i++) { int serviceBits = is.read(); if (serviceBits == 0) { tripDayOffset += 8; continue; } while ((serviceBits & 0x80) == 0) { serviceBits = serviceBits << 1; tripDayOffset++; } break; } is.reset(); is.skipBytes(tripDetailsPtr + tripDetailsIndexOffset + iTrip * 2); final int tripDetailsOffset = is.readShortReverse(); is.reset(); is.skipBytes(tripDetailsPtr + tripDetailsOffset); final int realtimeStatus = is.readShortReverse(); /* final short delay = */is.readShortReverse(); /* final int legIndex = */is.readShortReverse(); is.skipBytes(2); // 0xffff /* final int legStatus = */is.readShortReverse(); is.skipBytes(2); // 0x0000 String connectionId = null; if (tripAttrsPtr != 0) { is.reset(); is.skipBytes(tripAttrsPtr + iTrip * 2); final int tripAttrsIndex = is.readShortReverse(); is.reset(); is.skipBytes(attrsOffset + tripAttrsIndex * 4); while (true) { final String key = strings.read(is); if (key == null) break; else if (key.equals("ConnectionId")) connectionId = strings.read(is); else is.skipBytes(2); } } final List<Trip.Leg> legs = new ArrayList<>(numLegs); for (int iLegs = 0; iLegs < numLegs; iLegs++) { is.reset(); is.skipBytes(0x4a + legsOffset + iLegs * 20); final long plannedDepartureTime = time(is, resDate, tripDayOffset); final Location departureLocation = stations.read(is); final long plannedArrivalTime = time(is, resDate, tripDayOffset); final Location arrivalLocation = stations.read(is); final int type = is.readShortReverse(); final String lineName = strings.read(is); final Position plannedDeparturePosition = normalizePosition(strings.read(is)); final Position plannedArrivalPosition = normalizePosition(strings.read(is)); final int legAttrIndex = is.readShortReverse(); final List<Line.Attr> lineAttrs = new ArrayList<>(); String lineComment = null; boolean lineOnDemand = false; for (final String comment : comments.read(is)) { if (comment.startsWith("bf ")) { lineAttrs.add(Line.Attr.WHEEL_CHAIR_ACCESS); } else if (comment.startsWith("FA ") || comment.startsWith("FB ") || comment.startsWith("FR ")) { lineAttrs.add(Line.Attr.BICYCLE_CARRIAGE); } else if (comment.startsWith("$R ") || comment.startsWith("ga ") || comment.startsWith("ja ") || comment.startsWith("Vs ") || comment.startsWith("mu ") || comment.startsWith("mx ")) { lineOnDemand = true; lineComment = comment.substring(5); } } is.reset(); is.skipBytes(attrsOffset + legAttrIndex * 4); String directionStr = null; int lineClass = 0; String lineCategory = null; String routingType = null; String lineNetwork = null; while (true) { final String key = strings.read(is); if (key == null) break; else if (key.equals("Direction")) directionStr = strings.read(is); else if (key.equals("Class")) lineClass = Integer.parseInt(strings.read(is)); else if (key.equals("Category")) lineCategory = strings.read(is); // else if (key.equals("Operator")) // lineOperator = strings.read(is); else if (key.equals("GisRoutingType")) routingType = strings.read(is); else if (key.equals("AdminCode")) lineNetwork = normalizeLineAdministration(strings.read(is)); else is.skipBytes(2); } if (lineCategory == null && lineName != null) lineCategory = categoryFromName(lineName); is.reset(); is.skipBytes(tripDetailsPtr + tripDetailsOffset + tripDetailsLegOffset + iLegs * tripDetailsLegSize); if (tripDetailsLegSize != 16) throw new IllegalStateException( "unhandled trip details leg size: " + tripDetailsLegSize); final long predictedDepartureTime = time(is, resDate, tripDayOffset); final long predictedArrivalTime = time(is, resDate, tripDayOffset); final Position predictedDeparturePosition = normalizePosition(strings.read(is)); final Position predictedArrivalPosition = normalizePosition(strings.read(is)); final int bits = is.readShortReverse(); final boolean arrivalCancelled = (bits & 0x10) != 0; final boolean departureCancelled = (bits & 0x20) != 0; is.readShort(); final int firstStopIndex = is.readShortReverse(); final int numStops = is.readShortReverse(); is.reset(); is.skipBytes(disruptionsPtr); String disruptionText = null; if (is.readShortReverse() == 1) { is.reset(); is.skipBytes(disruptionsPtr + 2 + iTrip * 2); int disruptionsOffset = is.readShortReverse(); while (disruptionsOffset != 0) { is.reset(); is.skipBytes(disruptionsPtr + disruptionsOffset); strings.read(is); // "0" final int disruptionLeg = is.readShortReverse(); is.skipBytes(2); // bitmaske strings.read(is); // start of line strings.read(is); // end of line strings.read(is); // id /* final String disruptionTitle = */strings.read(is); final String disruptionShortText = ParserUtils.formatHtml(strings.read(is)); disruptionsOffset = is.readShortReverse(); // next if (iLegs == disruptionLeg) { final int disruptionAttrsIndex = is.readShortReverse(); is.reset(); is.skipBytes(attrsOffset + disruptionAttrsIndex * 4); while (true) { final String key = strings.read(is); if (key == null) break; else if (key.equals("Text")) disruptionText = ParserUtils.resolveEntities(strings.read(is)); else is.skipBytes(2); } if (disruptionShortText != null) disruptionText = disruptionShortText; } } } List<Stop> intermediateStops = null; if (numStops > 0) { is.reset(); is.skipBytes(tripDetailsPtr + stopsOffset + firstStopIndex * stopsSize); if (stopsSize != 26) throw new IllegalStateException("unhandled stops size: " + stopsSize); intermediateStops = new ArrayList<>(numStops); for (int iStop = 0; iStop < numStops; iStop++) { final long plannedStopDepartureTime = time(is, resDate, tripDayOffset); final Date plannedStopDepartureDate = plannedStopDepartureTime != 0 ? new Date(plannedStopDepartureTime) : null; final long plannedStopArrivalTime = time(is, resDate, tripDayOffset); final Date plannedStopArrivalDate = plannedStopArrivalTime != 0 ? new Date(plannedStopArrivalTime) : null; final Position plannedStopDeparturePosition = normalizePosition( strings.read(is)); final Position plannedStopArrivalPosition = normalizePosition(strings.read(is)); is.readInt(); final long predictedStopDepartureTime = time(is, resDate, tripDayOffset); final Date predictedStopDepartureDate = predictedStopDepartureTime != 0 ? new Date(predictedStopDepartureTime) : null; final long predictedStopArrivalTime = time(is, resDate, tripDayOffset); final Date predictedStopArrivalDate = predictedStopArrivalTime != 0 ? new Date(predictedStopArrivalTime) : null; final Position predictedStopDeparturePosition = normalizePosition( strings.read(is)); final Position predictedStopArrivalPosition = normalizePosition( strings.read(is)); final int stopBits = is.readShortReverse(); final boolean stopArrivalCancelled = (stopBits & 0x10) != 0; final boolean stopDepartureCancelled = (stopBits & 0x20) != 0; is.readShort(); final Location stopLocation = stations.read(is); final boolean validPredictedDate = !dominantPlanStopTime || (plannedStopArrivalDate != null && plannedStopDepartureDate != null); final Stop stop = new Stop(stopLocation, plannedStopArrivalDate, validPredictedDate ? predictedStopArrivalDate : null, plannedStopArrivalPosition, predictedStopArrivalPosition, stopArrivalCancelled, plannedStopDepartureDate, validPredictedDate ? predictedStopDepartureDate : null, plannedStopDeparturePosition, predictedStopDeparturePosition, stopDepartureCancelled); intermediateStops.add(stop); } } final Trip.Leg leg; if (type == 1 /* Fussweg */ || type == 3 /* Uebergang */ || type == 4 /* Uebergang */) { final Trip.Individual.Type individualType; if (routingType == null) individualType = type == 1 ? Trip.Individual.Type.WALK : Trip.Individual.Type.TRANSFER; else if ("FOOT".equals(routingType)) individualType = Trip.Individual.Type.WALK; else if ("BIKE".equals(routingType)) individualType = Trip.Individual.Type.BIKE; else if ("CAR".equals(routingType) || "P+R".equals(routingType)) individualType = Trip.Individual.Type.CAR; else throw new IllegalStateException("unknown routingType: " + routingType); final Date departureTime = new Date( predictedDepartureTime != 0 ? predictedDepartureTime : plannedDepartureTime); final Date arrivalTime = new Date( predictedArrivalTime != 0 ? predictedArrivalTime : plannedArrivalTime); final Trip.Leg lastLeg = legs.size() > 0 ? legs.get(legs.size() - 1) : null; if (lastLeg != null && lastLeg instanceof Trip.Individual && ((Trip.Individual) lastLeg).type == individualType) { final Trip.Individual lastIndividualLeg = (Trip.Individual) legs .remove(legs.size() - 1); leg = new Trip.Individual(individualType, lastIndividualLeg.departure, lastIndividualLeg.departureTime, arrivalLocation, arrivalTime, null, 0); } else { leg = new Trip.Individual(individualType, departureLocation, departureTime, arrivalLocation, arrivalTime, null, 0); } } else if (type == 2) { final Product lineProduct; if (lineOnDemand) lineProduct = Product.ON_DEMAND; else if (lineClass != 0) lineProduct = intToProduct(lineClass); else lineProduct = normalizeType(lineCategory); final Line line = newLine(lineNetwork, lineProduct, normalizeLineName(lineName), lineComment, lineAttrs.toArray(new Line.Attr[0])); final Location direction; if (directionStr != null) { final String[] directionPlaceAndName = splitStationName(directionStr); direction = new Location(LocationType.ANY, null, directionPlaceAndName[0], directionPlaceAndName[1]); } else { direction = null; } final Stop departure = new Stop(departureLocation, true, plannedDepartureTime != 0 ? new Date(plannedDepartureTime) : null, predictedDepartureTime != 0 ? new Date(predictedDepartureTime) : null, plannedDeparturePosition, predictedDeparturePosition, departureCancelled); final Stop arrival = new Stop(arrivalLocation, false, plannedArrivalTime != 0 ? new Date(plannedArrivalTime) : null, predictedArrivalTime != 0 ? new Date(predictedArrivalTime) : null, plannedArrivalPosition, predictedArrivalPosition, arrivalCancelled); leg = new Trip.Public(line, direction, departure, arrival, intermediateStops, null, disruptionText); } else { throw new IllegalStateException("unhandled type: " + type); } legs.add(leg); } final Trip trip = new Trip(connectionId, resDeparture, resArrival, legs, null, null, (int) numChanges); if (realtimeStatus != 2) // Verbindung fllt aus trips.add(trip); } // if result is only one single individual leg, don't query for more final boolean canQueryMore = trips.size() != 1 || trips.get(0).legs.size() != 1 || !(trips.get(0).legs.get(0) instanceof Trip.Individual); result.set(new QueryTripsResult(header, url.toString(), from, via, to, new QueryTripsBinaryContext(requestId, seqNr, ld, bis.getCount(), canQueryMore), trips)); } else { log.debug("Hafas error: {}", errorCode); if (errorCode == 1) { throw new SessionExpiredException(); } else if (errorCode == 2) { // F2: Your search results could not be stored internally. throw new SessionExpiredException(); } else if (errorCode == 8) { result.set(new QueryTripsResult(header, QueryTripsResult.Status.AMBIGUOUS)); return; } else if (errorCode == 13) { // IN13: Our booking system is currently being used by too many users at the same // time. result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } else if (errorCode == 19) { result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } else if (errorCode == 207) { // H207: Unfortunately your connection request can currently not be processed. result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } else if (errorCode == 887) { // H887: Your inquiry was too complex. Please try entering less intermediate stations. result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 890) { // H890: No connections have been found that correspond to your request. It is // possible // that the requested service does not operate from or to the places you stated on the // requested date of travel. result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 891) { // H891: Unfortunately there was no route found. Missing timetable data could be the // reason. result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 892) { // H892: Your inquiry was too complex. Please try entering less intermediate stations. result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 899) { // H899: there was an unsuccessful or incomplete search due to a timetable change. result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 900) { // Unsuccessful or incomplete search (timetable change) result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 9220) { // H9220: Nearby to the given address stations could not be found. result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNRESOLVABLE_ADDRESS)); return; } else if (errorCode == 9240) { // H9240: Unfortunately there was no route found. Perhaps your start or destination is // not // served at all or with the selected means of transport on the required date/time. result.set(new QueryTripsResult(header, QueryTripsResult.Status.NO_TRIPS)); return; } else if (errorCode == 9260) { // H9260: Unknown departure station result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNKNOWN_FROM)); return; } else if (errorCode == 9280) { // H9280: Unknown intermediate station result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNKNOWN_VIA)); return; } else if (errorCode == 9300) { // H9300: Unknown arrival station result.set(new QueryTripsResult(header, QueryTripsResult.Status.UNKNOWN_TO)); return; } else if (errorCode == 9320) { // The input is incorrect or incomplete result.set(new QueryTripsResult(header, QueryTripsResult.Status.INVALID_DATE)); return; } else if (errorCode == 9360) { // H9360: Unfortunately your connection request can currently not be processed. result.set(new QueryTripsResult(header, QueryTripsResult.Status.INVALID_DATE)); return; } else if (errorCode == 9380) { // H9380: Dep./Arr./Intermed. or equivalent station defined more than once result.set(new QueryTripsResult(header, QueryTripsResult.Status.TOO_CLOSE)); return; } else if (errorCode == 895) { // H895: Departure/Arrival are too near result.set(new QueryTripsResult(header, QueryTripsResult.Status.TOO_CLOSE)); return; } else if (errorCode == 65535) { result.set(new QueryTripsResult(header, QueryTripsResult.Status.SERVICE_DOWN)); return; } else { throw new IllegalStateException("error " + errorCode + " on " + url); } } } }, url); return result.get(); }