summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java
blob: 83b3cd8c4d089335dee52ed27a329655f166196a (plain) (blame)
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
// Copyright Yahoo. 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.component.ComponentSpecification;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry;
import com.yahoo.search.query.profile.types.QueryProfileType;
import com.yahoo.search.query.profile.types.QueryProfileTypeRegistry;

/**
 * A set of query profiles. This also holds the query profile types as a dependent registry
 *
 * @author bratseth
 */
public class QueryProfileRegistry extends ComponentRegistry<QueryProfile> {

    private QueryProfileTypeRegistry queryProfileTypeRegistry = new QueryProfileTypeRegistry();

    /** Register this type by its id */
    public void register(QueryProfile profile) {
        super.register(profile.getId(), profile);
    }

    /** Returns a query profile type by name, or null if not found */
    public QueryProfileType getType(String type) {
        return queryProfileTypeRegistry.getComponent(type);
    }

    /** Returns the type registry attached to this */
    public QueryProfileTypeRegistry getTypeRegistry() { return queryProfileTypeRegistry; }

    /**
     * <p>Returns a query profile for the given request string, or null if a suitable one is not found.</p>
     *
     * The request string must be a valid {@link com.yahoo.component.ComponentId} or null.
     *
     * <p>
     * If the string is null, the profile named "default" is returned, or null if that does not exists.
     *
     * <p>
     * The version part (if any) is matched used the usual component version patching rules.
     * If the name part matches a query profile name perfectly, that profile is returned.
     * If not, and the name is a slash-separated path, the profile with the longest matching left sub-path
     * which has a type which allows path mahting is used. If there is no such profile, null is returned.
     */
    public QueryProfile findQueryProfile(String idString) {
        if (idString==null) return getComponent("default");
        ComponentSpecification id=new ComponentSpecification(idString);
        QueryProfile profile=getComponent(id);
        if (profile!=null) return profile;

        return findPathParentQueryProfile(new ComponentSpecification(idString));
    }

    private QueryProfile findPathParentQueryProfile(ComponentSpecification id) {
        // Try the name with "/" appended - should have the same semantics with path matching
        QueryProfile slashedProfile=getComponent(new ComponentSpecification(id.getName() + "/",id.getVersionSpecification()));
        if (slashedProfile!=null && slashedProfile.getType()!=null && slashedProfile.getType().getMatchAsPath())
            return slashedProfile;

        // Extract the parent (if any)
        int slashIndex=id.getName().lastIndexOf("/");
        if (slashIndex<1) return null;
        String parentName=id.getName().substring(0,slashIndex);

        ComponentSpecification parentId=new ComponentSpecification(parentName,id.getVersionSpecification());

        QueryProfile pathParentProfile=getComponent(parentId);

        if (pathParentProfile!=null && pathParentProfile.getType()!=null && pathParentProfile.getType().getMatchAsPath())
            return pathParentProfile;
        return findPathParentQueryProfile(parentId);
    }

    /** Freezes this, and all owned query profiles and query profile types */
    @Override
    public void freeze() {
        if (isFrozen()) return;
        queryProfileTypeRegistry.freeze();
        for (QueryProfile queryProfile : allComponents())
            queryProfile.freeze();
    }

    public CompiledQueryProfileRegistry compile() { return QueryProfileCompiler.compile(this); }

}