1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.query.profile;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.protect.Validator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>A wrapper of a query profile where overrides to the values in the referenced
* profile can be set.</p>
*
* <p>This is used to allow configured overrides (in a particular referencing profile) of a referenced query profile.
*
* <p>Properties which are defined as not overridable in the type (if any) of the referenced query profile
* cannot be set.</p>
*
* @author bratseth
*/
public class BackedOverridableQueryProfile extends OverridableQueryProfile implements Cloneable {
/** The backing read only query profile, or null if this is not backed */
private final QueryProfile backingProfile;
/**
* Creates an overridable profile from the given backing profile. The backing profile will never be
* written to.
*
* @param backingProfile the backing profile, which is assumed read only, never null
*/
public BackedOverridableQueryProfile(QueryProfile backingProfile) {
Validator.ensureNotNull("An overridable query profile must be backed by a real query profile",backingProfile);
setType(backingProfile.getType());
this.backingProfile = backingProfile;
}
@Override
public String getSource() { return backingProfile.getSource(); }
@Override
public synchronized void freeze() {
super.freeze();
backingProfile.freeze();
}
@Override
protected Object localLookup(String localName, DimensionBinding dimensionBinding) {
Object valueInThis = super.localLookup(localName, dimensionBinding);
if (valueInThis != null) return valueInThis;
return backingProfile.localLookup(localName, dimensionBinding);
}
protected Boolean isLocalInstanceOverridable(String localName) {
Boolean valueInThis = super.isLocalInstanceOverridable(localName);
if (valueInThis != null) return valueInThis;
return backingProfile.isLocalInstanceOverridable(localName);
}
@Override
protected QueryProfile createSubProfile(String name, DimensionBinding dimensionBinding) {
Object backing = backingProfile.lookup(new CompoundName(name),
true,
dimensionBinding.createFor(backingProfile.getDimensions()));
if (backing instanceof QueryProfile)
return new BackedOverridableQueryProfile((QueryProfile)backing);
else
return new OverridableQueryProfile(); // Nothing is set in this branch, so nothing to override, but need override checking
}
/** Returns a clone of this which can be independently overridden, but which refers to the same backing profile */
@Override
public BackedOverridableQueryProfile clone() {
return (BackedOverridableQueryProfile)super.clone();
}
/** Returns the query profile backing this */
public QueryProfile getBacking() { return backingProfile; }
@Override
public void addInherited(QueryProfile inherited) {
backingProfile.addInherited(inherited);
}
void addInheritedHere(QueryProfile inherited) {
super.addInherited(inherited);
}
@Override
protected void visitVariants(boolean allowContent,QueryProfileVisitor visitor,DimensionBinding dimensionBinding) {
super.visitVariants(allowContent, visitor, dimensionBinding);
if (visitor.isDone()) return;
backingProfile.visitVariants(allowContent, visitor, dimensionBinding);
}
@Override
protected void visitInherited(boolean allowContent, QueryProfileVisitor visitor, DimensionBinding dimensionBinding, QueryProfile owner) {
super.visitInherited(allowContent, visitor, dimensionBinding, owner);
if (visitor.isDone()) return;
backingProfile.visitInherited(allowContent, visitor, dimensionBinding,owner);
}
/** Returns a value from the content of this: The value in this, or the value from the backing if not set in this */
protected Object getContent(String localKey) {
Object value = super.getContent(localKey);
if (value != null) return value;
return backingProfile.getContent(localKey);
}
/**
* Returns all the content from this:
* All the values in this, and all values in the backing where an overriding value is not set in this
*/
@Override
protected Map<String,Object> getContent() {
Map<String,Object> thisContent=super.getContent();
Map<String,Object> backingContent=backingProfile.getContent();
if (thisContent.isEmpty()) return backingContent; // Shortcut
if (backingContent.isEmpty()) return thisContent; // Shortcut
Map<String,Object> content=new HashMap<>(backingContent);
content.putAll(thisContent);
return content;
}
@Override
public String toString() {
return "overridable wrapper of " + backingProfile;
}
@Override
public boolean isExplicit() {
return backingProfile.isExplicit();
}
@Override
public List<String> getDimensions() {
List<String> dimensions = super.getDimensions();
if (dimensions != null) return dimensions;
return backingProfile.getDimensions();
}
}
|