1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 package org.apache.openoffice.comp.sdbc.dbtools.comphelper;
23 
24 import com.sun.star.container.NoSuchElementException;
25 import com.sun.star.container.XEnumeration;
26 import com.sun.star.container.XIndexAccess;
27 import com.sun.star.lang.EventObject;
28 import com.sun.star.lang.WrappedTargetException;
29 import com.sun.star.lang.XComponent;
30 import com.sun.star.lang.XEventListener;
31 import com.sun.star.lib.uno.helper.WeakBase;
32 import com.sun.star.uno.UnoRuntime;
33 
34 public class OEnumerationByIndex extends WeakBase implements XEnumeration, XEventListener {
35     private XIndexAccess collection;
36     private int position;
37     boolean isListening;
38 
OEnumerationByIndex(XIndexAccess collection)39     public OEnumerationByIndex(XIndexAccess collection) {
40         this.collection = collection;
41         startDisposeListening();
42     }
43 
44     @Override
disposing(EventObject event)45     public void disposing(EventObject event) {
46         synchronized (this) {
47             if (event.Source == collection) {
48                 collection = null;
49             }
50         }
51     }
52 
53     @Override
hasMoreElements()54     public boolean hasMoreElements() {
55         synchronized (this) {
56             if (collection != null) {
57                 if (position < collection.getCount()) {
58                     return true;
59                 } else {
60                     stopDisposeListening();
61                     collection = null;
62                 }
63             }
64             return false;
65         }
66     }
67 
68     @Override
nextElement()69     public Object nextElement()
70             throws NoSuchElementException, WrappedTargetException {
71         Object value = null;
72         synchronized (this) {
73             if (collection != null) {
74                 if (position < collection.getCount()) {
75                     try {
76                         value = collection.getByIndex(position++);
77                     } catch (com.sun.star.lang.IndexOutOfBoundsException indexOutOfBoundsException) {
78                         // can't happen
79                     }
80                 }
81                 if (position >= collection.getCount()) {
82                     stopDisposeListening();
83                     collection = null;
84                 }
85             }
86         }
87         if (value == null) {
88             throw new NoSuchElementException();
89         }
90         return value;
91     }
92 
startDisposeListening()93     private void startDisposeListening() {
94         synchronized (this) {
95             if (isListening) {
96                 return;
97             }
98             XComponent component = UnoRuntime.queryInterface(XComponent.class, collection);
99             if (component != null) {
100                 component.addEventListener(this);
101                 isListening = true;
102             }
103         }
104     }
105 
stopDisposeListening()106     private void stopDisposeListening() {
107         synchronized (this) {
108             if (!isListening) {
109                 return;
110             }
111             XComponent component = UnoRuntime.queryInterface(XComponent.class, collection);
112             if (component != null) {
113                 component.removeEventListener(this);
114                 isListening = false;
115             }
116         }
117     }
118 }
119