xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Scopes.java (revision e779faac6ac01c406f41e81a4354cd6ed590f968)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20  /*
21  * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
22  */
23 package org.opengrok.indexer.analysis;
24 
25 import org.opengrok.indexer.util.WhitelistObjectInputFilter;
26 
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.IOException;
30 import java.io.ObjectInputFilter;
31 import java.io.ObjectInputStream;
32 import java.io.ObjectOutputStream;
33 import java.io.Serializable;
34 import java.util.TreeSet;
35 
36 /**
37  *
38  * @author Tomas Kotal
39  */
40 public class Scopes implements Serializable {
41 
42     private static final long serialVersionUID = 1191703801007779489L;
43 
44     private static final ObjectInputFilter serialFilter = new WhitelistObjectInputFilter(
45             Scopes.class,
46             TreeSet.class,
47             Scope.class
48     );
49 
50     /**
51      * Note: this class has a natural ordering that is inconsistent with equals.
52      */
53     public static class Scope implements Serializable, Comparable<Scope> {
54 
55         private static final long serialVersionUID = 1191703801007779489L;
56 
57         private int lineFrom;
58         private int lineTo;
59         private String name;
60         private String namespace;
61         private String signature;
62 
Scope(int lineFrom, int lineTo, String name, String namespace)63         public Scope(int lineFrom, int lineTo, String name, String namespace) {
64             this(lineFrom, lineTo, name, namespace, "");
65         }
66 
Scope(int lineFrom, int lineTo, String name, String namespace, String signature)67         public Scope(int lineFrom, int lineTo, String name, String namespace, String signature) {
68             this.lineFrom = lineFrom;
69             this.lineTo = lineTo;
70             this.name = name;
71             this.namespace = namespace;
72             this.signature = signature;
73         }
74 
Scope(int lineFrom)75         public Scope(int lineFrom) {
76             this.lineFrom = lineFrom;
77         }
78 
matches(int line)79         public boolean matches(int line) {
80             return line >= lineFrom && line <= lineTo;
81         }
82 
83         @Override
compareTo(Scope o)84         public int compareTo(Scope o) {
85             return Integer.compare(lineFrom, o.lineFrom);
86         }
87 
getLineFrom()88         public int getLineFrom() {
89             return lineFrom;
90         }
91 
setLineFrom(int lineFrom)92         public void setLineFrom(int lineFrom) {
93             this.lineFrom = lineFrom;
94         }
95 
getLineTo()96         public int getLineTo() {
97             return lineTo;
98         }
99 
setLineTo(int lineTo)100         public void setLineTo(int lineTo) {
101             this.lineTo = lineTo;
102         }
103 
getName()104         public String getName() {
105             return name;
106         }
107 
setName(String name)108         public void setName(String name) {
109             this.name = name;
110         }
111 
getNamespace()112         public String getNamespace() {
113             return namespace;
114         }
115 
setNamespace(String namespace)116         public void setNamespace(String namespace) {
117             this.namespace = namespace;
118         }
119 
getSignature()120         public String getSignature() {
121             return signature;
122         }
123 
setSignature(String signature)124         public void setSignature(String signature) {
125             this.signature = signature;
126         }
127     }
128 
129     // default global scope
130     public static final Scope GLOBAL_SCOPE = new Scope(0, 0, "global", null, null);
131 
132     // tree of scopes sorted by starting line
133     private final TreeSet<Scope> scopes = new TreeSet<>();
134 
Scopes()135     public Scopes() {
136         // nothing to do here
137     }
138 
size()139     public int size() {
140         return scopes.size();
141     }
142 
addScope(Scope scope)143     public void addScope(Scope scope) {
144         scopes.add(scope);
145     }
146 
getScope(int line)147     public Scope getScope(int line) {
148         // find closest scope that starts before or on given line
149         Scope s = scopes.floor(new Scope(line));
150         return (s != null && s.matches(line)) ? s : GLOBAL_SCOPE;
151     }
152 
153     /**
154      * Create a binary representation of this object.
155      *
156      * @return a byte array representing this object
157      * @throws IOException if an error happens when writing to the array
158      */
serialize()159     public byte[] serialize() throws IOException {
160         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
161         new ObjectOutputStream(bytes).writeObject(this);
162         return bytes.toByteArray();
163     }
164 
165     /**
166      * De-serialize a binary representation of a {@code Definitions} object.
167      *
168      * @param bytes a byte array containing the {@code Definitions} object
169      * @return a {@code Definitions} object
170      * @throws IOException if an I/O error happens when reading the array
171      * @throws ClassNotFoundException if the class definition for an object
172      * stored in the byte array cannot be found
173      * @throws ClassCastException if the array contains an object of another
174      * type than {@code Definitions}
175      */
deserialize(byte[] bytes)176     public static Scopes deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
177         try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
178             in.setObjectInputFilter(serialFilter);
179             return (Scopes) in.readObject();
180         }
181     }
182 }
183