1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.core
.event
.aspect
;
15 import java
.util
.ArrayList
;
16 import java
.util
.List
;
18 import org
.eclipse
.jdt
.annotation
.Nullable
;
19 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
20 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
23 * Event aspect that resolves to a root event field, or one of its subfields.
25 * When used, the subfield pattern is slash-prefixed and slash-separated, and
26 * the backslash character is used to escape an uninterpreted slash.
28 * @author Patrick Tasse
30 public class TmfEventFieldAspect
implements ITmfEventAspect
<Object
> {
32 private static final char SLASH
= '/';
33 private static final char BACKSLASH
= '\\';
35 private final String fAspectName
;
36 private final IRootField fRootField
;
37 private final @Nullable String fFieldPath
;
38 private final String
[] fFieldArray
;
41 * Interface for the root field resolver
43 public interface IRootField
{
45 * Returns the root event field for this aspect. Implementations must
46 * override to provide a specific event member but should not assume the
47 * event is of any specific type.
50 * The event to process
51 * @return the root event field
53 public @Nullable ITmfEventField
getRootField(ITmfEvent event
);
60 * The name of the aspect. Should be localized.
62 * The field name or subfield pattern to resolve the event, or
63 * null to use the root field. Should *not* be localized!
65 * The root field resolver object
67 public TmfEventFieldAspect(String aspectName
, @Nullable String fieldPath
, IRootField rootField
) {
68 fAspectName
= aspectName
;
69 fFieldPath
= fieldPath
;
70 fFieldArray
= getFieldArray(fieldPath
);
71 fRootField
= rootField
;
75 * Get the field name or subfield pattern to resolve the event, or null if
76 * the root field is used.
78 * @return the field name, subfield pattern, or null
80 public @Nullable String
getFieldPath() {
85 * Create a new instance of the aspect for the specified field name or
86 * subfield pattern, relative to the root field, or null for the root
90 * The field name or subfield pattern to resolve the event, or
92 * @return a new aspect instance
94 public TmfEventFieldAspect
forField(@Nullable String fieldPath
) {
95 return new TmfEventFieldAspect(fAspectName
, fieldPath
, fRootField
);
99 public String
getName() {
104 public String
getHelpText() {
109 public @Nullable Object
resolve(ITmfEvent event
) {
110 ITmfEventField root
= fRootField
.getRootField(event
);
114 if (fFieldArray
.length
== 0) {
117 ITmfEventField field
= root
.getField(fFieldArray
);
121 return field
.getValue();
124 // ------------------------------------------------------------------------
126 // Typically we want identical field aspects to be merged together.
127 // ------------------------------------------------------------------------
130 public int hashCode() {
131 final int prime
= 31;
133 result
= prime
* result
+ fAspectName
.hashCode();
134 String fieldPath
= fFieldPath
;
135 result
= prime
* result
+ (fieldPath
== null ?
0 : fieldPath
.hashCode());
140 public boolean equals(@Nullable Object obj
) {
147 if (!this.getClass().equals(obj
.getClass())) {
150 TmfEventFieldAspect other
= (TmfEventFieldAspect
) obj
;
151 if (!fAspectName
.equals(other
.fAspectName
)) {
154 String fieldPath
= fFieldPath
;
155 if (fieldPath
== null) {
156 if (other
.fFieldPath
!= null) {
159 } else if (!fieldPath
.equals(other
.fFieldPath
)) {
165 private static String
[] getFieldArray(@Nullable String field
) {
168 return new String
[0];
171 if (field
.charAt(0) != SLASH
) {
172 return new String
[] { field
};
175 StringBuilder sb
= new StringBuilder();
176 List
<String
> list
= new ArrayList
<>();
178 // We start at 1 since the first character is a slash that we want to
180 for (int i
= 1; i
< field
.length(); i
++) {
181 char charAt
= field
.charAt(i
);
182 if (charAt
== SLASH
) {
183 // char is slash. Cut here.
184 list
.add(sb
.toString());
185 sb
= new StringBuilder();
186 } else if ((charAt
== BACKSLASH
) && (i
< field
.length() - 1) && (field
.charAt(i
+ 1) == SLASH
)) {
187 // Uninterpreted slash. Add it.
191 // Any other character. Add.
196 // Last block. Add it to list.
197 list
.add(sb
.toString());
199 // Transform to array
200 String
[] array
= new String
[list
.size()];