001/** 002 * 003 * Copyright © 2014 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smack.sm; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.List; 022import java.util.concurrent.BlockingQueue; 023 024import org.jivesoftware.smack.SmackException; 025import org.jivesoftware.smack.packet.Element; 026import org.jivesoftware.smack.packet.Stanza; 027 028public abstract class StreamManagementException extends SmackException { 029 030 public StreamManagementException() { 031 } 032 033 public StreamManagementException(String message) { 034 super(message); 035 } 036 037 /** 038 * 039 */ 040 private static final long serialVersionUID = 3767590115788821101L; 041 042 public static class StreamManagementNotEnabledException extends StreamManagementException { 043 044 /** 045 * 046 */ 047 private static final long serialVersionUID = 2624821584352571307L; 048 049 } 050 051 public static class StreamIdDoesNotMatchException extends StreamManagementException { 052 053 /** 054 * 055 */ 056 private static final long serialVersionUID = 1191073341336559621L; 057 058 public StreamIdDoesNotMatchException(String expected, String got) { 059 super("Stream IDs do not match. Expected '" + expected + "', but got '" + got + "'"); 060 } 061 } 062 063 public static class StreamManagementCounterError extends StreamManagementException { 064 065 /** 066 * 067 */ 068 private static final long serialVersionUID = 1L; 069 070 private final long handledCount; 071 private final long previousServerHandledCount; 072 private final long ackedStanzaCount; 073 private final int outstandingStanzasCount; 074 private final List<Stanza> ackedStanzas; 075 076 public StreamManagementCounterError(long handledCount, long previousServerHandlerCount, 077 long ackedStanzaCount, 078 List<Stanza> ackedStanzas) { 079 super( 080 "There was an error regarding the Stream Management counters. Server reported " 081 + handledCount 082 + " handled stanzas, which means that the " 083 + ackedStanzaCount 084 + " recently send stanzas by client are now acked by the server. But Smack had only " 085 + ackedStanzas.size() 086 + " to acknowledge. The stanza id of the last acked outstanding stanza is " 087 + (ackedStanzas.isEmpty() ? "<no acked stanzas>" 088 : ackedStanzas.get(ackedStanzas.size() - 1).getStanzaId())); 089 this.handledCount = handledCount; 090 this.previousServerHandledCount = previousServerHandlerCount; 091 this.ackedStanzaCount = ackedStanzaCount; 092 this.outstandingStanzasCount = ackedStanzas.size(); 093 this.ackedStanzas = Collections.unmodifiableList(ackedStanzas); 094 } 095 096 public long getHandledCount() { 097 return handledCount; 098 } 099 100 public long getPreviousServerHandledCount() { 101 return previousServerHandledCount; 102 } 103 104 public long getAckedStanzaCount() { 105 return ackedStanzaCount; 106 } 107 108 public int getOutstandingStanzasCount() { 109 return outstandingStanzasCount; 110 } 111 112 public List<Stanza> getAckedStanzas() { 113 return ackedStanzas; 114 } 115 } 116 117 public static final class UnacknowledgedQueueFullException extends StreamManagementException { 118 119 /** 120 * 121 */ 122 private static final long serialVersionUID = 1L; 123 124 private final int overflowElementNum; 125 private final int droppedElements; 126 private final List<Element> elements; 127 private final List<Stanza> unacknowledgesStanzas; 128 129 private UnacknowledgedQueueFullException(String message, int overflowElementNum, int droppedElements, List<Element> elements, 130 List<Stanza> unacknowledgesStanzas) { 131 super(message); 132 this.overflowElementNum = overflowElementNum; 133 this.droppedElements = droppedElements; 134 this.elements = elements; 135 this.unacknowledgesStanzas = unacknowledgesStanzas; 136 } 137 138 public int getOverflowElementNum() { 139 return overflowElementNum; 140 } 141 142 public int getDroppedElements() { 143 return droppedElements; 144 } 145 146 public List<Element> getElements() { 147 return elements; 148 } 149 150 public List<Stanza> getUnacknowledgesStanzas() { 151 return unacknowledgesStanzas; 152 } 153 154 public static UnacknowledgedQueueFullException newWith(int overflowElementNum, List<Element> elements, 155 BlockingQueue<Stanza> unacknowledgedStanzas) { 156 final int unacknowledgesStanzasQueueSize = unacknowledgedStanzas.size(); 157 List<Stanza> localUnacknowledgesStanzas = new ArrayList<>(unacknowledgesStanzasQueueSize); 158 localUnacknowledgesStanzas.addAll(unacknowledgedStanzas); 159 int droppedElements = elements.size() - overflowElementNum - 1; 160 161 String message = "The queue size " + unacknowledgesStanzasQueueSize + " is not able to fit another " 162 + droppedElements + " potential stanzas type top-level stream-elements."; 163 return new UnacknowledgedQueueFullException(message, overflowElementNum, droppedElements, elements, 164 localUnacknowledgesStanzas); 165 } 166 } 167} 168