001: /*_############################################################################
002: _##
003: _## SNMP4J-Agent - AbstractRequest.java
004: _##
005: _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
006: _##
007: _## Licensed under the Apache License, Version 2.0 (the "License");
008: _## you may not use this file except in compliance with the License.
009: _## You may obtain a copy of the License at
010: _##
011: _## http://www.apache.org/licenses/LICENSE-2.0
012: _##
013: _## Unless required by applicable law or agreed to in writing, software
014: _## distributed under the License is distributed on an "AS IS" BASIS,
015: _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: _## See the License for the specific language governing permissions and
017: _## limitations under the License.
018: _##
019: _##########################################################################*/
020:
021: package org.snmp4j.agent.request;
022:
023: import java.util.*;
024:
025: import org.snmp4j.smi.*;
026: import org.snmp4j.mp.SnmpConstants;
027: import org.snmp4j.PDU;
028:
029: /**
030: * The <code>AbstractRequest</code> implements common elements of SNMP and
031: * AgentX requests and might be also used for other sub-agent request types.
032: *
033: * @author Frank Fock
034: * @version 1.0
035: */
036: public abstract class AbstractRequest implements Request {
037:
038: protected List subrequests;
039: protected int phase = PHASE_INIT;
040: protected int errorStatus = 0;
041: protected int repeaterStartIndex;
042: protected int repeaterRowSize;
043: protected int reprocessCounter = 0;
044: protected int transactionID;
045:
046: public AbstractRequest() {
047: }
048:
049: public abstract boolean isBulkRequest();
050:
051: public SubRequest find(OID prefix) {
052: for (Iterator it = iterator(); it.hasNext();) {
053: SubRequest sreq = (SubRequest) it.next();
054: if (sreq.getVariableBinding().getOid().startsWith(prefix)) {
055: return sreq;
056: }
057: }
058: return null;
059: }
060:
061: protected synchronized void initSubRequests() {
062: if (subrequests == null) {
063: setupSubRequests();
064: }
065: }
066:
067: abstract protected void setupSubRequests();
068:
069: abstract protected int getMaxPhase();
070:
071: public int nextPhase() {
072: if (phase >= getMaxPhase()) {
073: throw new NoSuchElementException(
074: "Requested phase does not exists");
075: }
076: resetCompletionStatus();
077: switch (phase) {
078: case Request.PHASE_2PC_PREPARE: {
079: if (getErrorStatus() != PDU.noError) {
080: phase = Request.PHASE_2PC_CLEANUP;
081: } else {
082: phase = Request.PHASE_2PC_COMMIT;
083: }
084: break;
085: }
086: case Request.PHASE_2PC_COMMIT: {
087: if (getErrorStatus() != PDU.noError) {
088: phase = Request.PHASE_2PC_UNDO;
089: } else {
090: phase = Request.PHASE_2PC_CLEANUP;
091: }
092: break;
093: }
094: case Request.PHASE_2PC_UNDO: {
095: phase = Request.PHASE_2PC_CLEANUP;
096: break;
097: }
098: default: {
099: phase = Request.PHASE_2PC_PREPARE;
100: break;
101: }
102: }
103: return phase;
104: }
105:
106: public boolean isComplete() {
107: return ((getErrorStatus() != PDU.noError) || ((getPhase() >= getMaxPhase()) && isPhaseComplete()));
108: }
109:
110: public SubRequest get(int index) {
111: return (SubRequest) subrequests.get(index);
112: }
113:
114: public int getPhase() {
115: return phase;
116: }
117:
118: public int getErrorIndex() {
119: if (errorStatus == SnmpConstants.SNMP_ERROR_SUCCESS) {
120: return 0;
121: }
122: initSubRequests();
123: int index = 1;
124: for (Iterator it = subrequests.iterator(); it.hasNext(); index++) {
125: SubRequest sreq = (SubRequest) it.next();
126: if (sreq.getStatus().getErrorStatus() != SnmpConstants.SNMP_ERROR_SUCCESS) {
127: return index;
128: }
129: }
130: return 0;
131: }
132:
133: public int getErrorStatus() {
134: initSubRequests();
135: if (errorStatus == SnmpConstants.SNMP_ERROR_SUCCESS) {
136: for (Iterator it = subrequests.iterator(); it.hasNext();) {
137: SubRequest sreq = (SubRequest) it.next();
138: if (sreq.getStatus().getErrorStatus() != SnmpConstants.SNMP_ERROR_SUCCESS) {
139: return sreq.getStatus().getErrorStatus();
140: }
141: }
142: }
143: return errorStatus;
144: }
145:
146: public int getTransactionID() {
147: return transactionID;
148: }
149:
150: public void setPhase(int phase) throws NoSuchElementException {
151: if ((phase < 0) || (phase > getMaxPhase())) {
152: throw new NoSuchElementException(
153: "Illegal phase identifier: " + phase);
154: }
155: if (this .phase != phase) {
156: resetCompletionStatus();
157: }
158: this .phase = phase;
159: }
160:
161: protected void resetCompletionStatus() {
162: initSubRequests();
163: for (Iterator it = subrequests.iterator(); it.hasNext();) {
164: SubRequest subReq = (SubRequest) it.next();
165: subReq.getStatus().setPhaseComplete(false);
166: subReq.getStatus().setProcessed(false);
167: }
168: }
169:
170: public synchronized void resetProcessedStatus() {
171: for (Iterator it = subrequests.iterator(); it.hasNext();) {
172: SubRequest sreq = (SubRequest) it.next();
173: sreq.getStatus().setProcessed(
174: sreq.getStatus().isPhaseComplete());
175: }
176: }
177:
178: public void setErrorStatus(int errorStatus) {
179: this .errorStatus = errorStatus;
180: }
181:
182: public boolean equals(Object obj) {
183: if (obj instanceof Request) {
184: return (transactionID == ((Request) obj).getTransactionID());
185: }
186: return false;
187: }
188:
189: public int hashCode() {
190: return transactionID;
191: }
192:
193: public int getReprocessCounter() {
194: return reprocessCounter;
195: }
196:
197: public void incReprocessCounter() {
198: ++reprocessCounter;
199: }
200:
201: public String toString() {
202: return getClass().getName() + "[phase=" + phase
203: + ",errorStatus=" + errorStatus + ",transactionID="
204: + transactionID + ",repeaterStartIndex="
205: + repeaterStartIndex + ",repeaterRowSize="
206: + repeaterRowSize + ",reprocessCounter="
207: + reprocessCounter + ",subrequests=" + subrequests
208: + "]";
209: }
210:
211: }
|