Skip to content

Commit f9c4112

Browse files
committed
Add meta info to the event counting API
This meta info will be passed with the event during counting and can be used to determine the event origin. It can be also used in event processing API since it is passed to IEventDataFactory. DEVSIX-1958
1 parent e0df12d commit f9c4112

28 files changed

+414
-177
lines changed

kernel/src/main/java/com/itextpdf/kernel/counter/ContextManager.java

Lines changed: 12 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -95,82 +95,25 @@ public static ContextManager getInstance() {
9595
}
9696

9797
/**
98-
* Gets the top {@link IContext} based on the stack trace.
98+
* Gets the context associated with the passed class object.
99+
* The context is determined by class namespace.
99100
*
100-
* For example if the {@link PdfDocument} was created inside pdfHtml,
101-
* and the pdfHtml was called directly,
102-
* then calling this method from {@link PdfDocument} will retrieve pdfHtml context.
103-
*
104-
* @return the top {@link IContext} instance, or {@code null} if the context is unknown
101+
* @param clazz the class for which the context will be determined.
102+
* @return the {@link IContext} associated with the class, or {@code null} if the class is unknown.
105103
*/
106-
public IContext getTopContext() {
107-
return getTopContext(null);
104+
public IContext getContext(Class<?> clazz) {
105+
return clazz != null ? getContext(clazz.getName()) : null;
108106
}
109107

110108
/**
111-
* Gets the top {@link IContext} based on the stack trace.
112-
*
113-
* For example if the {@link PdfDocument} was created inside pdfHtml,
114-
* and the pdfHtml was called directly,
115-
* then calling this method from {@link PdfDocument} will retrieve pdfHtml context.
109+
* Gets the context associated with the passed class object.
110+
* The context is determined by class namespace.
116111
*
117-
* @param stop if this class is encountered during stack trace analysis,
118-
* then the process is stopped and {@code null} is returned
119-
* @return the top {@link IContext} instance, or {@code null}
120-
* if the context is unknown or {@code stop} is encountered
112+
* @param className the class name with the namespace for which the context will be determined.
113+
* @return the {@link IContext} associated with the class, or {@code null} if the class is unknown.
121114
*/
122-
public IContext getTopContext(Class<?> stop) {
123-
return getNamespaceMapping(getTopRecognisedNamespace(stop));
124-
}
125-
126-
/**
127-
* Gets the top recognised namespace based on the stack trace.
128-
*
129-
* For example if the {@link PdfDocument} was created inside pdfHtml,
130-
* and the pdfHtml was called directly,
131-
* then calling this method from {@link PdfDocument} will retrieve pdfHtml namespace.
132-
*
133-
* @return the top recognised namespace, or {@code null} if it is unrecognised
134-
*/
135-
public String getTopRecognisedNamespace() {
136-
return getTopRecognisedNamespace(null);
137-
}
138-
139-
/**
140-
* Gets the top recognised namespace based on the stack trace.
141-
*
142-
* For example if the {@link PdfDocument} was created inside pdfHtml,
143-
* and the pdfHtml was called directly,
144-
* then calling this method from {@link PdfDocument} will retrieve pdfHtml namespace.
145-
*
146-
* @param stop if this class is encountered during stack trace analysis,
147-
* then the process is stopped and {@code null} is returned
148-
* @return the top recognised namespace, or {@code null} if the context is unknown
149-
*/
150-
public String getTopRecognisedNamespace(Class<?> stop) {
151-
if (stop == null) {
152-
stop = getClass();
153-
}
154-
try {
155-
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
156-
String result;
157-
for(int i=trace.length-1; i>=0; --i){
158-
if (stop.getName().equals(trace[i].getClassName())) {
159-
return null;
160-
}
161-
result = getRecognisedNamespace(trace[i].getClassName());
162-
if (result != null) {
163-
return result;
164-
}
165-
}
166-
} catch (SecurityException e) {
167-
long current = SystemUtil.getRelativeTimeMillis();
168-
if (current - securityErrorLastLogged > SECURITY_ERROR_LOGGING_INTERVAL) {
169-
LoggerFactory.getLogger(getClass()).error(LogMessageConstant.UNABLE_TO_SEARCH_FOR_EVENT_CONTEXT);
170-
securityErrorLastLogged = current;
171-
}
172-
}
173-
return null;
115+
public IContext getContext(String className) {
116+
return getNamespaceMapping(getRecognisedNamespace(className));
174117
}
175118

176119
private String getRecognisedNamespace(String className) {

kernel/src/main/java/com/itextpdf/kernel/counter/DataHandlerCounter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ This file is part of the iText (R) project.
4949
import com.itextpdf.kernel.counter.data.EventDataHandlerUtil;
5050
import com.itextpdf.kernel.counter.data.EventData;
5151
import com.itextpdf.kernel.counter.event.IEvent;
52+
import com.itextpdf.kernel.counter.event.IMetaInfo;
5253

5354
/**
5455
* Counter based on {@link EventDataHandler}.
@@ -73,7 +74,7 @@ public DataHandlerCounter(EventDataHandler<T, V> dataHandler, IContext fallback)
7374
}
7475

7576
@Override
76-
protected void process(IEvent event) {
77-
dataHandler.register(event);
77+
protected void onEvent(IEvent event, IMetaInfo metaInfo) {
78+
dataHandler.register(event, metaInfo);
7879
}
7980
}

kernel/src/main/java/com/itextpdf/kernel/counter/DefaultEventCounter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ This file is part of the iText (R) project.
4747
import com.itextpdf.kernel.Version;
4848
import com.itextpdf.kernel.counter.context.UnknownContext;
4949
import com.itextpdf.kernel.counter.event.IEvent;
50+
import com.itextpdf.kernel.counter.event.IMetaInfo;
5051
import org.slf4j.Logger;
5152
import org.slf4j.LoggerFactory;
5253

@@ -102,7 +103,7 @@ public DefaultEventCounter() {
102103
"yBvdXIgc2FsZXMgZGVwYXJ0bWVudC4=");
103104

104105
@Override
105-
protected void process(IEvent event) {
106+
protected void onEvent(IEvent event, IMetaInfo metaInfo) {
106107
if (count.incrementAndGet() > repeatLevel) {
107108
if (Version.isAGPLVersion() || Version.isExpired() ) {
108109
String message = new String(message_1);

kernel/src/main/java/com/itextpdf/kernel/counter/EventCounter.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ This file is part of the iText (R) project.
4646
import com.itextpdf.kernel.counter.context.IContext;
4747
import com.itextpdf.kernel.counter.context.UnknownContext;
4848
import com.itextpdf.kernel.counter.event.IEvent;
49+
import com.itextpdf.kernel.counter.event.IMetaInfo;
4950

5051
/**
5152
* Class that can be extended if you want to count iText events, for example the number of documents
@@ -56,7 +57,7 @@ This file is part of the iText (R) project.
5657
*/
5758
public abstract class EventCounter {
5859

59-
private final IContext fallback;
60+
final IContext fallback;
6061

6162
/**
6263
* Creates instance of this class that allows all events from unknown {@link IContext}.
@@ -70,27 +71,17 @@ public EventCounter() {
7071
* @param fallback the {@link IContext} that will be used in case the event context is unknown
7172
*/
7273
public EventCounter(IContext fallback) {
73-
this.fallback = fallback;
74-
}
75-
76-
/**
77-
* Entry point for event processing. Some events may be discarded based on the event context.
78-
*
79-
* @param event {@link IEvent} to count
80-
* @param context event's {@link IContext}
81-
*/
82-
public final void onEvent(IEvent event, IContext context) {
83-
if (context == null) {
84-
context = fallback;
85-
}
86-
if (context.allow(event)) {
87-
process(event);
74+
if (fallback == null) {
75+
throw new IllegalArgumentException("The fallback context in EventCounter constructor cannot be null");
8876
}
77+
this.fallback = fallback;
8978
}
9079

9180
/**
9281
* The method that should be overridden for actual event processing
82+
*
9383
* @param event {@link IEvent} to count
84+
* @param metaInfo the {@link IMetaInfo} that can hold information about event origin
9485
*/
95-
abstract protected void process(IEvent event);
86+
protected abstract void onEvent(IEvent event, IMetaInfo metaInfo);
9687
}

kernel/src/main/java/com/itextpdf/kernel/counter/EventCounterHandler.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,14 @@ This file is part of the iText (R) project.
4545

4646
import com.itextpdf.kernel.counter.context.IContext;
4747
import com.itextpdf.kernel.counter.event.IEvent;
48+
import com.itextpdf.kernel.counter.event.IMetaInfo;
4849

49-
import java.util.Collections;
5050
import java.util.Map;
51-
import java.util.Set;
5251
import java.util.concurrent.ConcurrentHashMap;
5352

5453
/**
5554
* Manager that works with {@link IEventCounterFactory}. Create {@link EventCounter} for each registered {@link IEventCounterFactory}
56-
* and send corresponding events when calling {@link #onEvent(IEvent, Class)} method.
55+
* and send corresponding events when calling {@link #onEvent(IEvent, IMetaInfo, Class)} method.
5756
* <br/>
5857
* You can implement your own {@link IEventCounterFactory} and register them with {@link EventCounterHandler#register(IEventCounterFactory)}
5958
* Or implement {@link EventCounter} and register it with {@link SimpleEventCounterFactory} like this:
@@ -89,17 +88,27 @@ public static EventCounterHandler getInstance() {
8988
* Triggers all registered {@link IEventCounterFactory} to produce {@link EventCounter} instance
9089
* and count the event.
9190
*/
92-
public void onEvent(IEvent event, Class<?> caller) {
91+
public void onEvent(IEvent event, IMetaInfo metaInfo, Class<?> caller) {
9392
IContext context = null;
9493
boolean contextInitialized = false;
9594
for (IEventCounterFactory factory : factories.keySet()) {
9695
EventCounter counter = factory.getCounter(caller);
9796
if (counter != null) {
9897
if (!contextInitialized) {
99-
context = ContextManager.getInstance().getTopContext(getClass());
98+
if (metaInfo != null) {
99+
context = ContextManager.getInstance().getContext(metaInfo.getClass());
100+
}
101+
if (context == null) {
102+
context = ContextManager.getInstance().getContext(caller);
103+
}
104+
if (context == null) {
105+
context = ContextManager.getInstance().getContext(event.getClass());
106+
}
100107
contextInitialized = true;
101108
}
102-
counter.onEvent(event, context);
109+
if ((context != null && context.allow(event)) || (context == null && counter.fallback.allow(event))) {
110+
counter.onEvent(event, metaInfo);
111+
}
103112
}
104113
}
105114
}

kernel/src/main/java/com/itextpdf/kernel/counter/SystemOutEventCounter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ This file is part of the iText (R) project.
4545

4646
import com.itextpdf.io.util.MessageFormatUtil;
4747
import com.itextpdf.kernel.counter.event.IEvent;
48+
import com.itextpdf.kernel.counter.event.IMetaInfo;
4849

4950
/**
5051
* A {@link EventCounter} implementation that outputs event type to {@link System#out}
@@ -70,7 +71,7 @@ public SystemOutEventCounter(Class<?> cls) {
7071
}
7172

7273
@Override
73-
protected void process(IEvent event) {
74+
protected void onEvent(IEvent event, IMetaInfo metaInfo) {
7475
System.out.println(MessageFormatUtil.format("[{0}] {1} event", name, event.getEventType()));
7576
}
7677
}

kernel/src/main/java/com/itextpdf/kernel/counter/data/EventDataHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This file is part of the iText (R) project.
4545

4646
import com.itextpdf.io.util.SystemUtil;
4747
import com.itextpdf.kernel.counter.event.IEvent;
48-
import org.slf4j.LoggerFactory;
48+
import com.itextpdf.kernel.counter.event.IMetaInfo;
4949

5050
import java.util.Collections;
5151
import java.util.List;
@@ -95,11 +95,11 @@ public List<V> clear() {
9595
return all != null ? all : Collections.<V>emptyList();
9696
}
9797

98-
public void register(IEvent event) {
98+
public void register(IEvent event, IMetaInfo metaInfo) {
9999
V data;
100100
//Synchronization is left here mostly in consistency with cache and process, but factories are usually not thread safe anyway.
101101
synchronized (factory) {
102-
data = factory.create(event);
102+
data = factory.create(event, metaInfo);
103103
}
104104
if (data != null) {
105105
synchronized (cache) {

kernel/src/main/java/com/itextpdf/kernel/counter/data/IEventDataFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ This file is part of the iText (R) project.
4444
package com.itextpdf.kernel.counter.data;
4545

4646
import com.itextpdf.kernel.counter.event.IEvent;
47+
import com.itextpdf.kernel.counter.event.IMetaInfo;
4748

4849
/**
4950
* Interface that is responsible for creating new instance of {@link EventData}.
@@ -54,5 +55,5 @@ This file is part of the iText (R) project.
5455
*/
5556
public interface IEventDataFactory<T, V extends EventData<T>> {
5657

57-
V create(IEvent event);
58+
V create(IEvent event, IMetaInfo metaInfo);
5859
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
3+
This file is part of the iText (R) project.
4+
Copyright (c) 1998-2018 iText Group NV
5+
Authors: Bruno Lowagie, Paulo Soares, et al.
6+
7+
This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU Affero General Public License version 3
9+
as published by the Free Software Foundation with the addition of the
10+
following permission added to Section 15 as permitted in Section 7(a):
11+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
12+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
13+
OF THIRD PARTY RIGHTS
14+
15+
This program is distributed in the hope that it will be useful, but
16+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17+
or FITNESS FOR A PARTICULAR PURPOSE.
18+
See the GNU Affero General Public License for more details.
19+
You should have received a copy of the GNU Affero General Public License
20+
along with this program; if not, see http://www.gnu.org/licenses or write to
21+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
23+
http://itextpdf.com/terms-of-use/
24+
25+
The interactive user interfaces in modified source and object code versions
26+
of this program must display Appropriate Legal Notices, as required under
27+
Section 5 of the GNU Affero General Public License.
28+
29+
In accordance with Section 7(b) of the GNU Affero General Public License,
30+
a covered work must retain the producer line in every PDF that is created
31+
or manipulated using iText.
32+
33+
You can be released from the requirements of the license by purchasing
34+
a commercial license. Buying such a license is mandatory as soon as you
35+
develop commercial activities involving the iText software without
36+
disclosing the source code of your own applications.
37+
These activities include: offering paid services to customers as an ASP,
38+
serving PDFs on the fly in a web application, shipping iText with a closed
39+
source product.
40+
41+
For more information, please contact iText Software Corp. at this
42+
43+
*/
44+
package com.itextpdf.kernel.counter.event;
45+
46+
import java.io.Serializable;
47+
48+
/**
49+
* The meta info that can holds information about instance that throws the event
50+
*/
51+
public interface IMetaInfo extends Serializable {
52+
}

0 commit comments

Comments
 (0)