├── lib
├── javacc.jar
├── guava-r07.jar
├── junit-4.6.jar
├── easymock-2.5.jar
├── icu4j-4_0_1.jar
├── opencsv-1.8.jar
├── commons-lang-2.4.jar
└── commons-logging-1.1.1.jar
├── examples
└── src
│ ├── html
│ ├── csv_example.csv
│ ├── getting_started.html
│ └── all_examples.html
│ └── java
│ ├── SimpleExampleServlet.java
│ ├── SqlDataSourceServlet.java
│ └── CsvDataSourceServlet.java
├── src
├── main
│ └── java
│ │ └── com
│ │ └── google
│ │ └── visualization
│ │ └── datasource
│ │ ├── query
│ │ ├── SortOrder.java
│ │ ├── ColumnLookup.java
│ │ ├── DataTableColumnLookup.java
│ │ ├── engine
│ │ │ ├── RowTitle.java
│ │ │ ├── AggregationPath.java
│ │ │ ├── ColumnIndices.java
│ │ │ ├── MetaTable.java
│ │ │ └── TableRowComparator.java
│ │ ├── parser
│ │ │ ├── QueryOptionEnum.java
│ │ │ ├── GenericsHelper.java
│ │ │ └── QueryBuilder.java
│ │ ├── ColumnSort.java
│ │ ├── AggregationType.java
│ │ ├── GenericColumnLookup.java
│ │ ├── QueryFilter.java
│ │ ├── scalarfunction
│ │ │ ├── Upper.java
│ │ │ ├── Lower.java
│ │ │ ├── ScalarFunction.java
│ │ │ ├── CurrentDateTime.java
│ │ │ ├── Constant.java
│ │ │ ├── Sum.java
│ │ │ ├── Product.java
│ │ │ ├── Difference.java
│ │ │ ├── Modulo.java
│ │ │ └── Quotient.java
│ │ ├── QueryOptions.java
│ │ ├── ColumnIsNullFilter.java
│ │ ├── NegationFilter.java
│ │ ├── SimpleColumn.java
│ │ ├── QueryPivot.java
│ │ └── QueryGroup.java
│ │ ├── datatable
│ │ └── value
│ │ │ ├── NullValueException.java
│ │ │ ├── NumberValue.java
│ │ │ ├── TextValue.java
│ │ │ ├── BooleanValue.java
│ │ │ └── ValueType.java
│ │ ├── base
│ │ ├── TypeMismatchException.java
│ │ ├── InvalidQueryException.java
│ │ ├── StatusType.java
│ │ ├── Warning.java
│ │ ├── DataSourceException.java
│ │ ├── TextFormat.java
│ │ ├── OutputType.java
│ │ ├── ErrorMessages.java
│ │ └── ResponseStatus.java
│ │ ├── util
│ │ ├── CsvDataSourceException.java
│ │ └── SqlDatabaseDescription.java
│ │ ├── QueryPair.java
│ │ ├── DataSourceServlet.java
│ │ ├── DataTableGenerator.java
│ │ └── Capabilities.java
└── test
│ └── java
│ └── com
│ └── google
│ └── visualization
│ └── datasource
│ ├── base
│ ├── StatusTypeTest.java
│ ├── ReasonTypeTest.java
│ ├── LocaleUtilTest.java
│ └── ResponseStatusTest.java
│ ├── query
│ ├── engine
│ │ ├── AggregationPathTest.java
│ │ └── ColumnValueAggregatorTest.java
│ ├── scalarfunction
│ │ ├── LowerTest.java
│ │ ├── UpperTest.java
│ │ ├── ToDateTest.java
│ │ └── DateDiffTest.java
│ ├── ColumnColumnFilterTest.java
│ └── ColumnValueFilterTest.java
│ ├── datatable
│ ├── ColumnDescriptionTest.java
│ ├── value
│ │ └── ValueTest.java
│ └── TableRowTest.java
│ └── render
│ └── EscapeUtilTest.java
├── ReleaseNotes.txt
└── pom.xml
/lib/javacc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/javacc.jar
--------------------------------------------------------------------------------
/lib/guava-r07.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/guava-r07.jar
--------------------------------------------------------------------------------
/lib/junit-4.6.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/junit-4.6.jar
--------------------------------------------------------------------------------
/lib/easymock-2.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/easymock-2.5.jar
--------------------------------------------------------------------------------
/lib/icu4j-4_0_1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/icu4j-4_0_1.jar
--------------------------------------------------------------------------------
/lib/opencsv-1.8.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/opencsv-1.8.jar
--------------------------------------------------------------------------------
/lib/commons-lang-2.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/commons-lang-2.4.jar
--------------------------------------------------------------------------------
/examples/src/html/csv_example.csv:
--------------------------------------------------------------------------------
1 | Employee,Manager
2 | Roger,John
3 | Robert,John
4 | Jane,Roger
5 | Jack,Jane
6 | Bob,Jane
7 |
--------------------------------------------------------------------------------
/lib/commons-logging-1.1.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/google-visualization-java/HEAD/lib/commons-logging-1.1.1.jar
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/SortOrder.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | /**
18 | * Sort order.
19 | *
20 | * @author Yoah B.D.
21 | */
22 | public enum SortOrder {
23 | ASCENDING,
24 | DESCENDING
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/base/StatusTypeTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | import junit.framework.TestCase;
18 |
19 | /**
20 | * Unit test for StatusType.
21 | *
22 | * @author Nimrod T.
23 | */
24 | public class StatusTypeTest extends TestCase {
25 | public void testBasic() {
26 | StatusType statusType = StatusType.OK;
27 | assertEquals("ok", statusType.lowerCaseString());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/datatable/value/NullValueException.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable.value;
16 |
17 | /**
18 | * Exception that is thrown when there is an attempt to request the value of
19 | * a cell with a null value.
20 | *
21 | * @author Itai R.
22 | */
23 | public class NullValueException extends RuntimeException {
24 |
25 | /**
26 | * Constructor.
27 | *
28 | * @param message The detailed message of this exception.
29 | */
30 | public NullValueException(String message) {
31 | super(message);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/base/ReasonTypeTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | import junit.framework.TestCase;
18 |
19 |
20 | /**
21 | * Unit test for Helper.
22 | *
23 | * @author Yaniv S.
24 | */
25 | public class ReasonTypeTest extends TestCase {
26 |
27 | public void testBasic() {
28 | // Test getMessageForReasonType with default locale.
29 | assertEquals(ReasonType.INVALID_QUERY.getMessageForReasonType(), "Invalid query");
30 | }
31 |
32 | public void testLowerString() {
33 | ReasonType reasonType = ReasonType.ACCESS_DENIED;
34 | assertEquals("access_denied", reasonType.lowerCaseString());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/TypeMismatchException.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * This exception is thrown when there is a mismatch between a value type and a column type,
19 | * for example when trying to assign a boolean value to a column of type number.
20 | *
21 | * @author Yaniv S.
22 | */
23 | public class TypeMismatchException extends DataSourceException {
24 |
25 | /**
26 | * Constructs a new exception with OTHER reason type and a message for the user.
27 | *
28 | * @param message The message for the user.
29 | */
30 | public TypeMismatchException(String message) {
31 | super(ReasonType.OTHER, message);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/InvalidQueryException.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * An exception that is thrown when trying to serve an invalid query.
19 | * A query can fail at parsing time, or at later validations.
20 | *
21 | * @author Yonatan B.Y.
22 | * @author Hillel M.
23 | */
24 | public class InvalidQueryException extends DataSourceException {
25 |
26 | /**
27 | * Construct a data source exception with an InvalidQuery reason type
28 | * and a message to the user.
29 | *
30 | * @param messageToUser The message for the user.
31 | */
32 | public InvalidQueryException(String messageToUser) {
33 | super(ReasonType.INVALID_QUERY, messageToUser);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/util/CsvDataSourceException.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.util;
16 |
17 | import com.google.visualization.datasource.base.DataSourceException;
18 | import com.google.visualization.datasource.base.ReasonType;
19 |
20 | /**
21 | * An exception concerning the csv data source.
22 | *
23 | * @author Nimrod T.
24 | */
25 | public class CsvDataSourceException extends DataSourceException {
26 |
27 | /**
28 | * Constructor.
29 | * @param reasonType The reason type.
30 | * @param messageToUser A message that will be displayed to the end user.
31 | */
32 | public CsvDataSourceException(ReasonType reasonType, String messageToUser) {
33 | super(reasonType, messageToUser);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/ColumnLookup.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | /**
18 | * A column lookup.
19 | * Maps columns to their index in a column container (e.g., DateTable).
20 | *
21 | * @author Liron L.
22 | */
23 | public interface ColumnLookup {
24 |
25 | /**
26 | * Returns the index of the given column.
27 | *
28 | * @param column The given AbstractColumn.
29 | *
30 | * @return The index of the given column.
31 | */
32 | public int getColumnIndex(AbstractColumn column);
33 |
34 | /**
35 | * Returns whether or not this ColumnLookup contains the given column.
36 | *
37 | * @param column The column to check.
38 | *
39 | * @return True if column exists, false otherwise.
40 | */
41 | public boolean containsColumn(AbstractColumn column);
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/StatusType.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * An enum value to represent the status of a response.
19 | *
20 | * @author Hillel M.
21 | */
22 | public enum StatusType {
23 |
24 | /**
25 | * The query completed successfully and the data can be returned.
26 | */
27 | OK,
28 |
29 | /**
30 | * The query failed to complete. In this case, no data table is passed in the response.
31 | */
32 | ERROR,
33 |
34 | /**
35 | * The query completed with a warning. In some cases, part of the data is returned.
36 | */
37 | WARNING;
38 |
39 | /**
40 | * Returns a lower case string of this enum.
41 | *
42 | * @return a lower case string of this enum.
43 | */
44 | public String lowerCaseString() {
45 | return this.toString().toLowerCase();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/src/html/getting_started.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Getting Started Example
5 |
6 |
7 |
38 |
39 |
40 |
Hello! Data Source!
41 | A table chart that shows data taken from the simple data source.
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/base/LocaleUtilTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | import junit.framework.TestCase;
18 |
19 | import java.util.Locale;
20 |
21 | /**
22 | * Unit test for LocaleUtil.
23 | *
24 | * @author Hillel M.
25 | */
26 | public class LocaleUtilTest extends TestCase {
27 |
28 |
29 | public void testGetLocalizedMessageFromBundle() {
30 | assertEquals("Sign in", LocaleUtil.getLocalizedMessageFromBundle(
31 | "com.google.visualization.datasource.base.ErrorMessages", "SIGN_IN", null));
32 |
33 | assertEquals("Sign in", LocaleUtil.getLocalizedMessageFromBundle(
34 | "com.google.visualization.datasource.base.ErrorMessages", "SIGN_IN", Locale.CANADA_FRENCH));
35 |
36 | assertEquals("Access denied", LocaleUtil.getLocalizedMessageFromBundle(
37 | "com.google.visualization.datasource.base.ErrorMessages", "ACCESS_DENIED", Locale.GERMAN));
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/DataTableColumnLookup.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.visualization.datasource.datatable.DataTable;
18 |
19 | /**
20 | * An adapter between a data table and a column lookup.
21 | * The table does not have to contain rows; only the columns data is used.
22 | *
23 | * @author Liron L.
24 | */
25 | public class DataTableColumnLookup implements ColumnLookup {
26 |
27 | /**
28 | * The table.
29 | */
30 | private DataTable table;
31 |
32 | /**
33 | * Creates a new DataTableColumnLookup with the given data table.
34 | *
35 | * @param table The given TableDescription.
36 | */
37 | public DataTableColumnLookup(DataTable table) {
38 | this.table = table;
39 | }
40 |
41 | @Override
42 | public int getColumnIndex(AbstractColumn column) {
43 | return table.getColumnIndex(column.getId());
44 | }
45 |
46 | @Override
47 | public boolean containsColumn(AbstractColumn column) {
48 | return table.containsColumn(column.getId());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/Warning.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * A warning generated while processing a request.
19 | *
20 | * @author Yonatan B.Y.
21 | */
22 | public class Warning {
23 |
24 | /**
25 | * The reason for this warning.
26 | */
27 | private ReasonType reasonType;
28 |
29 | /**
30 | * The warning message to return to the user.
31 | */
32 | private String messageToUser;
33 |
34 | /**
35 | * Constructs a new exception with a reason type and a message for the user.
36 | *
37 | * @param reasonType The reason type of the exception.
38 | * @param messageToUser The message to the user.
39 | */
40 | public Warning(ReasonType reasonType, String messageToUser) {
41 | this.messageToUser = messageToUser;
42 | this.reasonType = reasonType;
43 | }
44 |
45 | /**
46 | * Returns the reason.
47 | *
48 | * @return The reason.
49 | */
50 | public ReasonType getReasonType() {
51 | return reasonType;
52 | }
53 |
54 | /**
55 | * Returns the message.
56 | *
57 | * @return The message.
58 | */
59 | public String getMessage() {
60 | return messageToUser;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/engine/RowTitle.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.visualization.datasource.datatable.value.Value;
18 |
19 | import java.util.List;
20 |
21 | /**
22 | * A "title" (identification) of a row in a pivoted and/or grouped table.
23 | * What identifies a row is the list of values, one value from each of the group-by columns.
24 | *
25 | * @author Yonatan B.Y.
26 | */
27 | /* package */ class RowTitle {
28 |
29 | /**
30 | * The values of the group-by columns that identify the row.
31 | */
32 | public List values;
33 |
34 | /**
35 | * Creates a new instance with the given list of group-by column values.
36 | *
37 | * @param values The list of group-by column values.
38 | */
39 | public RowTitle(List values) {
40 | this.values = values;
41 | }
42 |
43 | @Override
44 | public boolean equals(Object o) {
45 | if (this == o) {
46 | return true;
47 | }
48 | if (!(o instanceof RowTitle)) {
49 | return false;
50 | }
51 | RowTitle other = (RowTitle) o;
52 | return values.equals(other.values);
53 | }
54 |
55 |
56 | @Override
57 | public int hashCode() {
58 | return values.hashCode();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/ReleaseNotes.txt:
--------------------------------------------------------------------------------
1 | Version 1.1.2
2 | -----------------------------------------
3 | - Fix security threat of swf injection in jsonp.
4 |
5 | Version 1.1.1
6 | -----------------------------------------
7 | - Move from google-collect-1.0 to guava-r07.
8 | - Changed Json output to be valid Json format: Added quotation marks around
9 | all keys and string values. Date values are formated as"Date(2011,1,1)".
10 | Note: for jsonp dates remain as they were before and the Date object is
11 | returned in the json string, e.g., new Date(2011,1,1).
12 | - Added setCell method to DataTable class.
13 | - Added support for SKIPPING clause in the query language.
14 | - Added support for MODULO operator in the query language.
15 | - Fixed bug: Response content type for JSON/P is not valid.
16 | - Fixed bug: java.util.TreeMap initialization in QueryEngine causes
17 | compilation error.
18 | - Fixed bug: Where clause with column names that contain spaces does not work
19 | for SQL datasources (Issue 16).
20 | - Fixed bug: SQL data source dates are shifted (Issue 11).
21 | - Changed initialization of Timestamp in SQLDataSourceHelperTest.
22 | - Add a message to the IllegalArgumentException thrown when a
23 | DateValue/DateTimeValue/TimeOfDayValue is created with a GregorianCalendar
24 | that is not GMT.
25 | - Externalized error messages.
26 | - Removed unnecessary servlet from web.xml.
27 |
28 | Version 1.0.2
29 | -----------------------------------------
30 | - Added maven build (pom.xml).
31 | - Starting with this version this library is available in a maven web repository.
32 | - Added tests.
33 | - Added support for LIKE operator in the query language.
34 | - Fixed bug: Export to HTML double escapes   (Issue 2).
35 | - Fixed bug: Format and label clauses do not work for queries that contain
36 | scalar functions (Issue 3).
37 | - Fixed bug: "is null" in the where clause of a query does not work for SQL
38 | datasources (Issue 4).
39 | - Fixed bug: CSV output does not escape non text values with commas (Issue 5).
40 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/parser/QueryOptionEnum.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.parser;
16 |
17 | import com.google.visualization.datasource.query.QueryOptions;
18 |
19 | /**
20 | * Helper enum for the auto-generated parser. Holds a single query option (a single element of the
21 | * OPTIONS clause). This is used by the parser, i.e., referenced from the QueryParser.jj file.
22 | * It is needed because queryOptions uses boolean setX() functions, and does not have a datatype
23 | * to hold a single value, and such a datatype is needed for convenience of parsing purposes in
24 | * the .jj parser. You can use the setInQueryOptions() method of this enum, to set the option to
25 | * true in a QueryOptions instance.
26 | *
27 | * @author Yonatan B.Y.
28 | */
29 | /* package */ enum QueryOptionEnum {
30 | NO_VALUES,
31 | NO_FORMAT;
32 |
33 | /**
34 | * Sets this option to true in the given QueryOptions, leaving its other
35 | * options intact.
36 | *
37 | * @param queryOptions The QueryOptions in which to set the option to true.
38 | */
39 | public void setInQueryOptions(QueryOptions queryOptions) {
40 | switch (this) {
41 | case NO_VALUES:
42 | queryOptions.setNoValues(true);
43 | break;
44 | case NO_FORMAT:
45 | queryOptions.setNoFormat(true);
46 | break;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/engine/AggregationPathTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.visualization.datasource.datatable.value.NumberValue;
18 | import com.google.visualization.datasource.datatable.value.Value;
19 |
20 | import junit.framework.TestCase;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * Tests for the AggregationPath class
26 | *
27 | * @author Yoav G.
28 | */
29 |
30 | public class AggregationPathTest extends TestCase {
31 |
32 | public void simpleTest() {
33 | AggregationPath path = new AggregationPath();
34 | path.add(new NumberValue(3));
35 | path.add(new NumberValue(4));
36 | List values = path.getValues();
37 | assertEquals(3.0, ((NumberValue) values.get(0)).getValue());
38 | assertEquals(4.0, ((NumberValue) values.get(1)).getValue());
39 | }
40 |
41 | public void testReverse() {
42 | AggregationPath path = new AggregationPath();
43 | path.add(new NumberValue(3));
44 | path.add(new NumberValue(4));
45 | path.reverse();
46 | List values = path.getValues();
47 | assertEquals(4.0, ((NumberValue) values.get(0)).getValue());
48 | assertEquals(3.0, ((NumberValue) values.get(1)).getValue());
49 | }
50 |
51 | public void testEmptyPath() {
52 | AggregationPath path = new AggregationPath();
53 | path.reverse();
54 | List values = path.getValues();
55 | assertEquals(0, values.size());
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/ColumnSort.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | /**
18 | * A sort definition for a single column.
19 | * This class is immutable.
20 | *
21 | * @author Yoah B.D.
22 | */
23 | public class ColumnSort {
24 |
25 | /**
26 | * The column by which to sort.
27 | */
28 | private AbstractColumn column;
29 |
30 | /**
31 | * The requested ordering.
32 | */
33 | private SortOrder order;
34 |
35 | /**
36 | * Construct and new column sort condition.
37 | * @param column The column by which to sort.
38 | * @param order The requested ordering.
39 | */
40 | public ColumnSort(AbstractColumn column, SortOrder order) {
41 | this.column = column;
42 | this.order = order;
43 | }
44 |
45 | /**
46 | * Returns the column by which to sort.
47 | * @return The column by which to sort.
48 | */
49 | public AbstractColumn getColumn() {
50 | return column;
51 | }
52 |
53 | /**
54 | * Returns the requested ordering.
55 | * @return The requested ordering.
56 | */
57 | public SortOrder getOrder() {
58 | return order;
59 | }
60 |
61 | /**
62 | * Creates a string that when fed to the query parser should return a ColumnSort equal to this
63 | * one. Used mainly for debugging purposes.
64 | * @return A query string.
65 | */
66 | public String toQueryString() {
67 | return column.toQueryString() + (order == SortOrder.DESCENDING ? " DESC" : "");
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/engine/AggregationPath.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.common.collect.ImmutableList;
18 | import com.google.common.collect.Lists;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 |
21 | import java.util.Collections;
22 | import java.util.List;
23 |
24 | /**
25 | * An ordered list of values representing a path in an aggregation tree, from the root to a node.
26 | * Only the values are stored, not the nodes themselves.
27 | *
28 | * @author Yoav G.
29 | */
30 |
31 | public class AggregationPath {
32 |
33 | /**
34 | * The list of values forming the path. Each value, in turn, is used to
35 | * navigate down from the current node to one of its children.
36 | */
37 | private List values;
38 |
39 | /**
40 | * Construct an empty path.
41 | */
42 | public AggregationPath() {
43 | values = Lists.newArrayList();
44 | }
45 |
46 | /**
47 | * Adds a value to this path.
48 | *
49 | * @param value The value to add.
50 | */
51 | public void add(Value value) {
52 | values.add(value);
53 | }
54 |
55 | /**
56 | * Returns the list of values. This list is immutable.
57 | *
58 | * @return The list of values. This list is immutable.
59 | */
60 |
61 | public List getValues() {
62 | return ImmutableList.copyOf(values);
63 | }
64 |
65 | /**
66 | * Reverses this path.
67 | */
68 | public void reverse() {
69 | Collections.reverse(values);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/QueryPair.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource;
16 |
17 | import com.google.visualization.datasource.query.Query;
18 |
19 | /**
20 | * A product of splitQuery() method, composed of a data source query to be executed first by
21 | * the data source and a second completion query to be executed on the results of the
22 | * first one by the query engine.
23 | * The application of the first query and the second query is equivalent to the application of the
24 | * original query.
25 | *
26 | * @author Yonatan B.Y.
27 | */
28 | public class QueryPair {
29 |
30 | /**
31 | * The data source query.
32 | */
33 | private Query dataSourceQuery;
34 |
35 | /**
36 | * The completion query.
37 | */
38 | private Query completionQuery;
39 |
40 | /**
41 | * Construct a new query pair.
42 | *
43 | * @param dataSourceQuery The data source query.
44 | * @param completionQuery The completion query.
45 | */
46 | public QueryPair(Query dataSourceQuery, Query completionQuery) {
47 | this.dataSourceQuery = dataSourceQuery;
48 | this.completionQuery = completionQuery;
49 | }
50 |
51 | /**
52 | * Returns the data source query.
53 | *
54 | * @return The data source query.
55 | */
56 | public Query getDataSourceQuery() {
57 | return dataSourceQuery;
58 | }
59 |
60 | /**
61 | * Returns the completion query.
62 | *
63 | * @return The completion query.
64 | */
65 | public Query getCompletionQuery() {
66 | return completionQuery;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/DataSourceServlet.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource;
16 |
17 | import java.io.IOException;
18 |
19 | import javax.servlet.http.HttpServlet;
20 | import javax.servlet.http.HttpServletRequest;
21 | import javax.servlet.http.HttpServletResponse;
22 |
23 | /**
24 | * An abstract class for data source servlet implementations.
25 | *
26 | * @author Yaniv S.
27 | */
28 | public abstract class DataSourceServlet extends HttpServlet implements DataTableGenerator {
29 |
30 | @Override
31 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
32 | DataSourceHelper.executeDataSourceServletFlow(req, resp, this, isRestrictedAccessMode());
33 | }
34 |
35 | /**
36 | * Returns a flag that indicates whether the servlet is in restricted-access mode.
37 | * In restricted-access mode the server serves only requests coming from the same domain as the
38 | * server domain (i.e., same origin policy).
39 | * This protects the server from XSRF attacks while limiting the requests to which the server
40 | * can respond.
41 | *
42 | * @return True if this servlet operates in restricted-access mode, false otherwise.
43 | */
44 | protected boolean isRestrictedAccessMode() {
45 | return true;
46 | }
47 |
48 | @Override
49 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
50 | doGet(req, resp);
51 | }
52 |
53 | @Override
54 | public Capabilities getCapabilities() {
55 | return Capabilities.NONE;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/DataTableGenerator.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource;
16 |
17 | import com.google.visualization.datasource.base.DataSourceException;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.query.Query;
20 |
21 | import javax.servlet.http.HttpServletRequest;
22 |
23 | /**
24 | * An interface for a class that can generate a DataTable.
25 | *
26 | * @author Yaniv S.
27 | */
28 | public interface DataTableGenerator {
29 |
30 | /**
31 | * Generates the data table.
32 | *
33 | * @param query The query to execute on the underlying data. Ignore this parameter for
34 | * a data source that does not support any capabilities.
35 | * @param request The http request. May contain information that is relevant to generating
36 | * the data table.
37 | *
38 | * @return The generated data table.
39 | *
40 | * @throws DataSourceException If the data could not be generated for any reason.
41 | */
42 | public DataTable generateDataTable(Query query, HttpServletRequest request)
43 | throws DataSourceException;
44 |
45 | /**
46 | * Returns the capabilities supported by this data table generator.
47 | *
48 | * The query that generateDataTable accepts will only contain clauses
49 | * corresponding to these capabilities.
50 | * (see {@link com.google.visualization.datasource.Capabilities}).
51 | *
52 | * @return The capabilities supported by this datasource.
53 | */
54 | public Capabilities getCapabilities();
55 | }
56 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/datatable/ColumnDescriptionTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable;
16 |
17 | import com.google.visualization.datasource.datatable.value.ValueType;
18 |
19 | import junit.framework.TestCase;
20 |
21 | /**
22 | * ColumnDescription Tester.
23 | *
24 | * @author Hillel M.
25 | */
26 | public class ColumnDescriptionTest extends TestCase {
27 |
28 | private ColumnDescription columnDescription;
29 |
30 | public void testConstructor() {
31 | columnDescription = new ColumnDescription("col123", ValueType.TIMEOFDAY, "123");
32 | assertNotNull(columnDescription);
33 | }
34 |
35 | public void testGetId() {
36 | columnDescription = new ColumnDescription("col123", ValueType.TIMEOFDAY, "123");
37 | assertEquals("col123", columnDescription.getId());
38 | }
39 |
40 | public void testGetType() {
41 | columnDescription = new ColumnDescription("col123", ValueType.TIMEOFDAY, "123");
42 | assertEquals(ValueType.TIMEOFDAY, columnDescription.getType());
43 | }
44 |
45 |
46 | public void testGetLabel() {
47 | columnDescription = new ColumnDescription("col123", ValueType.TIMEOFDAY, "123");
48 | assertEquals("123", columnDescription.getLabel());
49 | }
50 |
51 | public void testColumnProperties() {
52 | columnDescription = new ColumnDescription("col123", ValueType.BOOLEAN, "123");
53 | assertNull(columnDescription.getCustomProperty("brandy"));
54 |
55 | columnDescription.setCustomProperty("brandy", "cognac");
56 | assertEquals("cognac", columnDescription.getCustomProperty("brandy"));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/render/EscapeUtilTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.render;
16 |
17 |
18 | import junit.framework.TestCase;
19 |
20 | /**
21 | * Tests for Escape Util.
22 | *
23 | * @author Hillel M.
24 | */
25 | public class EscapeUtilTest extends TestCase{
26 |
27 | public static void testJsonEscape() {
28 | // Check ' " < > \
29 | assertEquals("\\u0027ABC", EscapeUtil.jsonEscape("'ABC"));
30 | assertEquals("\\u0022ABC", EscapeUtil.jsonEscape("\"ABC"));
31 | assertEquals("\\\\", EscapeUtil.jsonEscape("\\"));
32 | assertEquals("\\u003cABC\\u003e", EscapeUtil.jsonEscape(""));
33 | assertEquals("\\u003c/ABC\\u003e", EscapeUtil.jsonEscape(""));
34 |
35 | // Normal string (all keyboard letters but ', ", \, <, >)
36 | String normalString = "`1234567890-=qwertyuiop[];lkjhgfdsazxcvbnm,.//*-+.0~!@#$%^&*()_+"
37 | + "QWERTYUIOP{}|:LKJHGFDSAZXCVBNM?;";
38 | assertEquals(normalString, EscapeUtil.jsonEscape(normalString));
39 |
40 | // Weird characters (non readable)
41 | String weirdString = "\n\t\r\\ \u0081\u0010\u2010\u2099\b\f";
42 | String escapedweirdString = "\\n\\t\\r\\\\ \\u0081\\u0010\\u2010\\u2099\\b\\f";
43 | assertEquals(escapedweirdString, EscapeUtil.jsonEscape(weirdString));
44 |
45 | // Normal string in Unicode (pqr)
46 | String normalStringInUnicode = "\u0070\u0071\u0072";
47 | assertEquals("pqr", EscapeUtil.jsonEscape(normalStringInUnicode));
48 |
49 | // Non English normal characters (Hebrew - me)
50 | String nonEnglishString = "\u05d0\u05e0\u05d9";
51 | assertEquals(nonEnglishString, EscapeUtil.jsonEscape(nonEnglishString));
52 | }
53 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/AggregationType.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.common.collect.Maps;
18 |
19 | import java.util.Map;
20 |
21 | /**
22 | * Enumeration of all possible aggregation types.
23 | *
24 | * @author Yoav G.
25 | * @author Yonatan B.Y.
26 | */
27 | public enum AggregationType {
28 | SUM("sum"),
29 | COUNT("count"),
30 | MIN("min"),
31 | MAX("max"),
32 | AVG("avg");
33 |
34 | /**
35 | * The code for this AggregationType.
36 | */
37 | private String code;
38 |
39 | /**
40 | * Constructor
41 | *
42 | * @param code The code for this AggregationType.
43 | */
44 | private AggregationType(String code) {
45 | this.code = code;
46 | }
47 |
48 | /**
49 | * Get this AggregationType code.
50 | *
51 | * @return The AggregationType code.
52 | */
53 | public String getCode() {
54 | return code;
55 | }
56 |
57 | /**
58 | * Returns the correct AggregationType for a given code.
59 | *
60 | * @param code The code for a type.
61 | *
62 | * @return The correct AggregationType for the given code.
63 | */
64 | public static AggregationType getByCode(String code) {
65 | return codeToAggregationType.get(code);
66 | }
67 |
68 | /**
69 | * Holds the mapping of type code to instances of this class.
70 | */
71 | private static Map codeToAggregationType;
72 |
73 | /**
74 | * Initializes the static maps.
75 | */
76 | static {
77 | codeToAggregationType = Maps.newHashMap();
78 | for (AggregationType type : AggregationType.values()) {
79 | codeToAggregationType.put(type.code, type);
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/parser/GenericsHelper.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.parser;
16 |
17 | import com.google.common.collect.Lists;
18 |
19 | import java.util.ArrayList;
20 | import java.util.Arrays;
21 | import java.util.List;
22 |
23 |
24 | /**
25 | * Helper functions to assist the generated parser to deal with generic types. Unfortunately,
26 | * javacc is not good at handling generic types, such as List, inside
27 | * the .jj file. One solution is to use ArrayLists in the .jj file and then convert them
28 | * using this class. This class uses unsafe operations, which is unavoidable.
29 | *
30 | * @author Yonatan B.Y.
31 | */
32 | /* package */ class GenericsHelper {
33 | private GenericsHelper()
34 | {}
35 |
36 | /**
37 | * Transforms, in an unsafe way, a typed List from a raw ArrayList.
38 | *
39 | * @param list The ArrayList to transform.
40 | *
41 | * @return The new List containing all the elements in list.
42 | */
43 | /* package */ static List makeTypedList(ArrayList extends T> list) {
44 | List result = Lists.newArrayListWithExpectedSize(list.size());
45 | for (T obj : list) {
46 | result.add(obj);
47 | }
48 | return result;
49 | }
50 |
51 | /**
52 | * Transforms a typed List from a raw array.
53 | *
54 | * @param array The array to transform.
55 | *
56 | * @return The new List containing all the elements in array.
57 | */
58 | /* package */ static List makeAbstractColumnList(T[] array) {
59 | List result = Lists.newArrayListWithExpectedSize(array.length);
60 | result.addAll(Arrays.asList(array));
61 | return result;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/GenericColumnLookup.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.common.collect.Maps;
18 |
19 | import java.util.Map;
20 |
21 | /**
22 | * This class represents a generic column lookup. It maps an abstract
23 | * column to its index in a table description.
24 | *
25 | * @author Liron L.
26 | */
27 | public class GenericColumnLookup implements ColumnLookup {
28 |
29 | /**
30 | * A map from the column to its index in the table description.
31 | */
32 | private Map columnIndexByColumn;
33 |
34 | /**
35 | * Create a GenericColumnLookup (with an empty map).
36 | */
37 | public GenericColumnLookup() {
38 | columnIndexByColumn = Maps.newHashMap();
39 | }
40 |
41 | /**
42 | * Clear all data of this GenericColumnLookup.
43 | */
44 | public void clear() {
45 | columnIndexByColumn.clear();
46 | }
47 |
48 | /**
49 | * Sets the index of the given column to the given number.
50 | *
51 | * @param col The column to set the index of.
52 | * @param index The index to set for the column.
53 | */
54 | public void put(AbstractColumn col, int index) {
55 | columnIndexByColumn.put(col, index);
56 | }
57 |
58 | /**
59 | * Returns the column index in the columns of a row (first is zero).
60 | *
61 | * @param column The column.
62 | *
63 | * @return The column index in the columns of a row (first is zero).
64 | */
65 | public int getColumnIndex(AbstractColumn column) {
66 | return columnIndexByColumn.get(column);
67 | }
68 |
69 | @Override
70 | public boolean containsColumn(AbstractColumn column) {
71 | return columnIndexByColumn.containsKey(column);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/Capabilities.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource;
16 |
17 | /**
18 | * An enumeration of the capabilities provided by a data source. A data source declares the
19 | * capabilities it supports and this information determines how a query is split.
20 | * For example if a data source declares Capibilities.SELECT then the following
21 | * query select A,B sort A limit 20
22 | * will be split as follows:
23 | * query for data source - 'select A,B'
24 | * completion query - 'sort A limit 20'
25 | *
26 | * @author Yonatan B.Y.
27 | */
28 | public enum Capabilities {
29 |
30 | /**
31 | * Supports: filter, sort, group, limit, and offset.
32 | * Does not support: pivot, options, labels, format or scalar functions.
33 | */
34 | SQL,
35 |
36 | /**
37 | * Supports: sort, limit, and offset over simple columns.
38 | * Simple columns are those that are not aggregation columns (such as max(a),
39 | * count(b), avg(c)) or scalar function columns (like a+b, c*2, year(d)).
40 | * If calculated columns are created, through scalar functions or aggregation for example,
41 | * the completion query handles the SORT_AND_PAGINATION over the newly created columns.
42 | */
43 | SORT_AND_PAGINATION,
44 |
45 | /**
46 | * Supports: select over simple columns.
47 | *
48 | * If calculated columns are created, through scalar functions or aggregation for example,
49 | * the completion query handles the SELECT over the newly created columns.
50 | */
51 | SELECT,
52 |
53 | /**
54 | * Supports all the above capabilities: SQL. SORT_AND_PAGINATION, and SELECT.
55 | */
56 | ALL,
57 |
58 | /**
59 | * Supports no capabilities.
60 | */
61 | NONE
62 | }
63 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/datatable/value/ValueTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable.value;
16 |
17 | import junit.framework.TestCase;
18 |
19 | /**
20 | * Value Tester.
21 | *
22 | * @author Hillel M.
23 | */
24 | public class ValueTest extends TestCase {
25 |
26 | public void testCompareTo() {
27 | Value val1 = new DateValue(2007, 1, 23);
28 | Value val2 = new DateValue(2007, 1, 23);
29 | Value val4 = new DateValue(2007, 1, 20);
30 |
31 | Value valTime1 = new TimeOfDayValue(10, 11, 21, 222);
32 |
33 | // Equal objects.
34 | assertTrue(0 == val1.compareTo(val1));
35 | assertTrue(0 == val1.compareTo(val2));
36 | assertTrue(0 == val2.compareTo(val1));
37 |
38 | // Same class x > y.
39 | assertTrue(0 < val2.compareTo(val4));
40 | assertTrue(0 > val4.compareTo(val2));
41 |
42 | // Different class x > y.
43 | try {
44 | val2.compareTo(valTime1);
45 | fail();
46 | } catch (ClassCastException e) {
47 | // Expected behavior.
48 | }
49 | }
50 |
51 | public void testEquals() {
52 | Number number = new Double(-12.3);
53 | Value numberValue1 = new NumberValue(-12.3);
54 | Value numberValue2 = new NumberValue(-12.3);
55 | Value numberValue3 = new NumberValue(12.3343);
56 | Value timeValue = new TimeOfDayValue(12, 1, 2, 3);
57 |
58 | // null == other.
59 | assertFalse(numberValue1.equals(null));
60 |
61 | // other.Class != this.Class.
62 | assertFalse(numberValue1.equals(timeValue));
63 | assertFalse(timeValue.equals(numberValue1));
64 | assertFalse(numberValue1.equals(number));
65 |
66 | // this == other.
67 | assertTrue(numberValue2.equals(numberValue2));
68 |
69 | // equal objects.
70 | assertTrue(numberValue1.equals(numberValue2));
71 |
72 | // not equal Values.
73 | assertFalse(numberValue1.equals(numberValue3));
74 | assertFalse(numberValue1.equals(timeValue));
75 | }
76 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/DataSourceException.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * An exception to be used by callers and callees of the library.
19 | * Each exception has a type taken from ReasonType, and a
20 | * message that can be used to output an appropriate message to the user.
21 | *
22 | * Example:
23 | * new DataSourceException(ReasonType.InvalidQuery, "The query cannot be empty")
24 | *
25 | * @author Hillel M.
26 | */
27 |
28 | public class DataSourceException extends Exception {
29 |
30 | /**
31 | * The reason for this exception. Used to set the reason type of this
32 | * execution response by the thrower of this exception.
33 | */
34 | private ReasonType reasonType;
35 |
36 | /**
37 | * The error message to return to the user.
38 | */
39 | private String messageToUser = null;
40 |
41 | /**
42 | * A private constructor to prevent using this exception with no message.
43 | */
44 | private DataSourceException() {}
45 |
46 | /**
47 | * Constructs a new exception with a single message for the user.
48 | *
49 | * @param reasonType The reason type of the exception.
50 | * @param messageToUser The message for the user.
51 | */
52 | public DataSourceException(ReasonType reasonType, String messageToUser) {
53 | super(messageToUser);
54 | this.messageToUser = messageToUser;
55 | this.reasonType = reasonType;
56 | }
57 |
58 | /**
59 | * Returns the message for the user.
60 | *
61 | * @return The message for the user.
62 | */
63 | public String getMessageToUser() {
64 | return messageToUser;
65 | }
66 |
67 | /**
68 | * Returns the reason type of this exception.
69 | *
70 | * @return The reason type of this exception.
71 | */
72 | public ReasonType getReasonType() {
73 | return reasonType;
74 | }
75 |
76 | @Override @Deprecated
77 | public String getMessage() {
78 | return super.getMessage();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/QueryFilter.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.visualization.datasource.datatable.DataTable;
18 | import com.google.visualization.datasource.datatable.TableRow;
19 |
20 | import java.util.List;
21 | import java.util.Set;
22 |
23 | /**
24 | * A query filter.
25 | * Any class that implements this interface can act as a filter, i.e., be the
26 | * part of a query that decides for a given TableRow if that row is part of the
27 | * result set.
28 | *
29 | * @author Yonatan B.Y.
30 | */
31 | public abstract class QueryFilter {
32 |
33 | /**
34 | * Checks if this row should be part of the result set.
35 | *
36 | * @param table The table containing this row.
37 | * @param row The row to check.
38 | *
39 | * @return true if this row should be part of the result set, false otherwise.
40 | */
41 | public abstract boolean isMatch(DataTable table, TableRow row);
42 |
43 | /**
44 | * Returns all the columnIds this filter uses.
45 | *
46 | * @return All the columnIds this filter uses.
47 | */
48 | public abstract Set getAllColumnIds();
49 |
50 | /**
51 | * Returns a list of all scalarFunctionColumns this filter uses.
52 | *
53 | * @return A list of all scalarFunctionColumns this filter uses.
54 | */
55 | public abstract List getScalarFunctionColumns();
56 |
57 | /**
58 | * Returns a list of all aggregation columns this filter uses. This is kept for future use, as
59 | * currently filters are not allowed to have aggregation columns. This is still used currently
60 | * for validation purposes.
61 | *
62 | * @return A list of all aggregation columns this filter uses.
63 | */
64 | protected abstract List getAggregationColumns();
65 |
66 | /**
67 | * Returns a string that, when parsed by the query parser, should return an
68 | * identical filter. The string returned does not contain the WHERE keyword.
69 | *
70 | * @return A string form of this filter.
71 | */
72 | public abstract String toQueryString();
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/TextFormat.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | import com.ibm.icu.text.UFormat;
18 |
19 | import java.text.FieldPosition;
20 | import java.text.ParsePosition;
21 |
22 | /**
23 | * A UFormat that performs (dummy) formatting and parsing of text (string) values.
24 | *
25 | * This class is required only to be consistent with the UFormat API, its methods do nothing.
26 | *
27 | * @author Hillel M.
28 | */
29 | public class TextFormat extends UFormat {
30 |
31 | /**
32 | * Formats a TextValue and appends the result to a StringBuffer.
33 | *
34 | * @param obj The object to format.
35 | * @param appendTo The StringBuffer to which the formatted string is appended.
36 | * @param pos A FieldPosition parameter not used in this case.
37 | *
38 | * @return A StringBuffer with the formatted string for this object.
39 | */
40 | @Override
41 | public StringBuffer format(Object obj, StringBuffer appendTo, FieldPosition pos) {
42 | if ((null == obj) || !(obj instanceof String)) {
43 | throw new IllegalArgumentException();
44 | }
45 | String text = (String) obj;
46 | appendTo.append(text);
47 | pos.setBeginIndex(0);
48 | if (0 == text.length()) {
49 | pos.setEndIndex(0);
50 | } else {
51 | pos.setEndIndex(text.length() - 1);
52 | }
53 | return appendTo;
54 | }
55 |
56 | /**
57 | * Parse a string into a TextValue.
58 | *
59 | * If this method is used to parse an empty string and it is called via
60 | * Format.parseObject(Object) a ParseException is thrown.
61 | *
62 | * @param source The string to parse from.
63 | * @param pos Marks the end of the parsing or 0 if the parsing failed.
64 | *
65 | * @return A BooleanValue for the parsed string.
66 | *
67 | * @throws NullPointerException if pos is null or source is null.
68 | */
69 | @Override
70 | public Object parseObject(String source, ParsePosition pos) {
71 | if ((null == pos) || (null == source)) {
72 | throw new NullPointerException();
73 | }
74 | pos.setIndex(source.length());
75 | return source;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/scalarfunction/LowerTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.common.collect.Lists;
18 | import com.google.visualization.datasource.base.InvalidQueryException;
19 | import com.google.visualization.datasource.datatable.value.TextValue;
20 | import com.google.visualization.datasource.datatable.value.Value;
21 | import com.google.visualization.datasource.datatable.value.ValueType;
22 |
23 | import junit.framework.TestCase;
24 |
25 |
26 | /**
27 | * Tests for the DateDiff scalar function.
28 | *
29 | * @author Yaniv S.
30 | */
31 | public class LowerTest extends TestCase {
32 | public void testValidateParameters() {
33 | Lower lower = Lower.getInstance();
34 |
35 | // Verify that Lower does not accept 0 parameters.
36 | try {
37 | lower.validateParameters(Lists.newArrayList());
38 | fail();
39 | } catch (InvalidQueryException e) {
40 | // Do nothing - this is the expected behavior.
41 | }
42 |
43 | // Verify that Lower does not accept more than 1 parameter.
44 | try {
45 | lower.validateParameters(Lists.newArrayList(ValueType.TEXT,
46 | ValueType.TEXT));
47 | fail();
48 | } catch (InvalidQueryException e) {
49 | // Do nothing - this is the expected behavior.
50 | }
51 |
52 | // Verify that Lower does not accept a non-Text parameter.
53 | try {
54 | lower.validateParameters(Lists.newArrayList(ValueType.DATE));
55 | fail();
56 | } catch (InvalidQueryException e) {
57 | // Do nothing - this is the expected behavior.
58 | }
59 |
60 | // Verify that Lower accepts 1 TEXT parameter.
61 | try {
62 | lower.validateParameters(Lists.newArrayList(ValueType.TEXT));
63 | } catch (InvalidQueryException e) {
64 | fail();
65 | }
66 | }
67 |
68 | public void testEvaluate() {
69 | Lower lower = Lower.getInstance();
70 |
71 | // Test empty string.
72 | TextValue textValue = (TextValue) lower.evaluate(
73 | Lists.newArrayList(new TextValue("")));
74 | assertEquals(textValue.getValue(), "");
75 |
76 | // Basic test.
77 | textValue = (TextValue) lower.evaluate(
78 | Lists.newArrayList(new TextValue("AbC")));
79 | assertEquals(textValue.getValue(), "abc");
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/scalarfunction/UpperTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.common.collect.Lists;
18 | import com.google.visualization.datasource.base.InvalidQueryException;
19 | import com.google.visualization.datasource.datatable.value.TextValue;
20 | import com.google.visualization.datasource.datatable.value.Value;
21 | import com.google.visualization.datasource.datatable.value.ValueType;
22 |
23 | import junit.framework.TestCase;
24 |
25 |
26 | /**
27 | * Tests for the Upper scalar function.
28 | *
29 | * @author Yaniv S.
30 | */
31 | public class UpperTest extends TestCase {
32 | public void testValidateParameters() {
33 | Upper upper = Upper.getInstance();
34 |
35 | // Verify that Upper does not accept 0 parameters.
36 | try {
37 | upper.validateParameters(Lists.newArrayList());
38 | fail();
39 | } catch (InvalidQueryException e) {
40 | // Do nothing - this is the expected behavior.
41 | }
42 |
43 | // Verify that Upper does not accept more than 1 parameter.
44 | try {
45 | upper.validateParameters(Lists.newArrayList(ValueType.TEXT,
46 | ValueType.TEXT));
47 | fail();
48 | } catch (InvalidQueryException e) {
49 | // Do nothing - this is the expected behavior.
50 | }
51 |
52 | // Verify that Upper does not accept a non-Text parameter.
53 | try {
54 | upper.validateParameters(Lists.newArrayList(ValueType.DATE));
55 | fail();
56 | } catch (InvalidQueryException e) {
57 | // Do nothing - this is the expected behavior.
58 | }
59 |
60 | // Verify that Upper accepts 1 TEXT parameter.
61 | try {
62 | upper.validateParameters(Lists.newArrayList(ValueType.TEXT));
63 | } catch (InvalidQueryException e) {
64 | fail();
65 | }
66 | }
67 |
68 | public void testEvaluate() {
69 | Upper upper = Upper.getInstance();
70 |
71 | // Test empty string.
72 | TextValue textValue = (TextValue) upper.evaluate(
73 | Lists.newArrayList(new TextValue("")));
74 | assertEquals(textValue.getValue(), "");
75 |
76 | // Basic test.
77 | textValue = (TextValue) upper.evaluate(
78 | Lists.newArrayList(new TextValue("aBc")));
79 | assertEquals(textValue.getValue(), "ABC");
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/engine/ColumnIndices.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.common.collect.ArrayListMultimap;
18 | import com.google.common.collect.ImmutableList;
19 | import com.google.visualization.datasource.query.AbstractColumn;
20 |
21 | import java.util.List;
22 |
23 | /**
24 | * Holds a mapping between {@link AbstractColumn}s and lists of indices, i.e., holds a list of
25 | * indices for each column. The indices for a column are the indices in the new datatable, generated
26 | * by a grouping/pivoting operation. There may be many indices for one column because a pivoting
27 | * operation creates a few columns for a single original column.
28 | *
29 | * @author Yonatan B.Y.
30 | */
31 | /* package */ class ColumnIndices {
32 |
33 | /**
34 | * The indices of the columns.
35 | */
36 | private ArrayListMultimap columnToIndices;
37 | /**
38 | * Creates an empty instance of this class.
39 | */
40 | public ColumnIndices() {
41 | columnToIndices = ArrayListMultimap.create();
42 | }
43 |
44 | /**
45 | * Sets the index of the given column to the given number.
46 | *
47 | * @param col The column to set the index of.
48 | * @param index The index to set for the column.
49 | */
50 | public void put(AbstractColumn col, int index) {
51 | columnToIndices.put(col, index);
52 | }
53 |
54 | /**
55 | * Returns the index of the given column. If there is more than one index for
56 | * the column, a runtime exception is thrown.
57 | *
58 | * @param col The column to look for.
59 | *
60 | * @return The index of the column.
61 | */
62 | public int getColumnIndex(AbstractColumn col) {
63 | List indices = columnToIndices.get(col);
64 | if (indices.size() != 1) {
65 | throw new RuntimeException("Invalid use of ColumnIndices.");
66 | }
67 | return indices.get(0);
68 | }
69 |
70 | /**
71 | * Returns the indices of the given column.
72 | *
73 | * @param col The column to look for.
74 | *
75 | * @return The indeices of the column.
76 | */
77 | public List getColumnIndices(AbstractColumn col) {
78 | return ImmutableList.copyOf(columnToIndices.get(col));
79 | }
80 |
81 | /**
82 | * Clears the entire map.
83 | */
84 | public void clear() {
85 | columnToIndices.clear();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/datatable/TableRowTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable;
16 |
17 | import com.google.visualization.datasource.datatable.value.BooleanValue;
18 | import com.google.visualization.datasource.datatable.value.DateValue;
19 | import com.google.visualization.datasource.datatable.value.NumberValue;
20 | import com.google.visualization.datasource.datatable.value.TextValue;
21 |
22 | import junit.framework.TestCase;
23 |
24 | /**
25 | * Tests for TableRow
26 | *
27 | * @author Yonatan B.Y.
28 | */
29 | public class TableRowTest extends TestCase {
30 |
31 | @Override
32 | public void setUp() throws Exception {
33 | super.setUp();
34 | }
35 |
36 | @Override
37 | public void tearDown() throws Exception {
38 | super.tearDown();
39 | }
40 |
41 | public void testClone() throws Exception {
42 | TableRow row = new TableRow();
43 | row.addCell(true);
44 | row.addCell(BooleanValue.getNullValue());
45 | row.addCell(-2.3);
46 | row.addCell("foo");
47 | row.addCell(new DateValue(2008, 2, 3));
48 | row.getCell(2).setFormattedValue("bar-2.3");
49 | row.getCell(4).setCustomProperty("foo", "bar");
50 |
51 | TableRow clonedRow = row.clone();
52 |
53 | assertEquals(true, ((BooleanValue) clonedRow.getCell(0).getValue()).getValue());
54 | assertTrue(clonedRow.getCell(1).isNull());
55 | assertEquals(-2.3, ((NumberValue) clonedRow.getCell(2).getValue()).getValue());
56 | assertEquals("foo", ((TextValue) clonedRow.getCell(3).getValue()).getValue());
57 | assertEquals(3, ((DateValue) clonedRow.getCell(4).getValue()).getDayOfMonth());
58 | assertEquals("bar-2.3", clonedRow.getCell(2).getFormattedValue());
59 | assertEquals("bar", clonedRow.getCell(4).getCustomProperty("foo"));
60 | assertEquals(1, clonedRow.getCell(4).getCustomProperties().size());
61 |
62 | assertTrue(clonedRow != row);
63 | assertTrue(clonedRow.getCell(0) != row.getCell(0));
64 | assertTrue(clonedRow.getCell(1) != row.getCell(1));
65 | assertTrue(clonedRow.getCell(4).getCustomProperties() != row.getCell(4).getCustomProperties());
66 |
67 | row.getCell(0).setCustomProperty("foo2", "bar2");
68 | assertTrue(clonedRow.getCell(0).getCustomProperties().isEmpty());
69 |
70 | clonedRow.getCell(3).setCustomProperty("foo3", "bar3");
71 | assertTrue(row.getCell(3).getCustomProperties().isEmpty());
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Upper.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.TextValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * A unary scalar function that changes text to upper case.
26 | *
27 | * @author Yaniv S.
28 | */
29 | public class Upper implements ScalarFunction {
30 |
31 | /**
32 | * The name of this function.
33 | */
34 | private static final String FUNCTION_NAME = "upper";
35 |
36 | /**
37 | * A singleton instance of this class.
38 | */
39 | private static final Upper INSTANCE = new Upper();
40 |
41 | /**
42 | * A private constructor, to prevent instantiation other than by the singleton.
43 | */
44 | private Upper() {}
45 |
46 | /**
47 | * @return The singleton instance of this class.
48 | */
49 | public static Upper getInstance() {
50 | return INSTANCE;
51 | }
52 |
53 | /**
54 | * {@inheritDoc}
55 | */
56 | public String getFunctionName() {
57 | return FUNCTION_NAME;
58 | }
59 |
60 | /**
61 | * @param values A list that contains one text value.
62 | *
63 | * @return An uppercase version of the input text value.
64 | */
65 | public Value evaluate(List values) {
66 | return new TextValue(((TextValue) values.get(0)).getValue().toUpperCase());
67 | }
68 |
69 | /**
70 | * @return The return type of this function - TEXT.
71 | */
72 | public ValueType getReturnType(List types) {
73 | return ValueType.TEXT;
74 | }
75 |
76 | /**
77 | * {@inheritDoc}
78 | */
79 | public void validateParameters(List types) throws InvalidQueryException {
80 | if (types.size() != 1) {
81 | throw new InvalidQueryException(FUNCTION_NAME +
82 | " requires 1 parmaeter");
83 | }
84 | if (types.get(0) != ValueType.TEXT) {
85 | throw new InvalidQueryException(FUNCTION_NAME +
86 | " takes a text parameter");
87 | }
88 | }
89 |
90 | /**
91 | * {@inheritDoc}
92 | */
93 | public String toQueryString(List argumentsQueryStrings) {
94 | return FUNCTION_NAME + "(" + argumentsQueryStrings.get(0) + ")";
95 | }
96 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Lower.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.TextValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * A unary scalar function that changes text to lower case.
26 | *
27 | * @author Yaniv S.
28 | */
29 | public class Lower implements ScalarFunction {
30 |
31 | /**
32 | * The name of this function.
33 | */
34 | private static final String FUNCTION_NAME = "lower";
35 |
36 | /**
37 | * A singleton instance of this class.
38 | */
39 | private static final Lower INSTANCE = new Lower();
40 |
41 | /**
42 | * A private constructor, to prevent instantiation other than by the singleton.
43 | */
44 | private Lower() {}
45 |
46 | /**
47 | * @return The singleton instance of this class.
48 | */
49 | public static Lower getInstance() {
50 | return INSTANCE;
51 | }
52 |
53 | /**
54 | * {@inheritDoc}
55 | */
56 | public String getFunctionName() {
57 | return FUNCTION_NAME;
58 | }
59 |
60 | /**
61 | * @param values A list that contains one text value.
62 | *
63 | * @return A lower-case version of the input text value.
64 | */
65 | public Value evaluate(List values) {
66 | return new TextValue(((TextValue) values.get(0)).getValue().toLowerCase());
67 | }
68 |
69 | /**
70 | * @return The return type of this function - TEXT.
71 | */
72 | public ValueType getReturnType(List types) {
73 | return ValueType.TEXT;
74 | }
75 |
76 | /**
77 | * {@inheritDoc}
78 | */
79 | public void validateParameters(List types) throws InvalidQueryException {
80 | if (types.size() != 1) {
81 | throw new InvalidQueryException(FUNCTION_NAME +
82 | " requires 1 parmaeter");
83 | }
84 | if (types.get(0) != ValueType.TEXT) {
85 | throw new InvalidQueryException(FUNCTION_NAME +
86 | " takes a text parameter");
87 | }
88 | }
89 |
90 | /**
91 | * {@inheritDoc}
92 | */
93 | public String toQueryString(List argumentsQueryStrings) {
94 | return FUNCTION_NAME + "(" + argumentsQueryStrings.get(0) + ")";
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/util/SqlDatabaseDescription.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.util;
16 |
17 | /**
18 | * This class contains all information required to connect to the sql database.
19 | *
20 | * @author Liron L.
21 | */
22 | public class SqlDatabaseDescription {
23 |
24 | /**
25 | * The url of the sql database.
26 | */
27 | private String url;
28 |
29 | /**
30 | * The user name used to access the sql database.
31 | */
32 | private String user;
33 |
34 | /**
35 | * The password used to access the sql database.
36 | */
37 | private String password;
38 |
39 | /**
40 | * The database table name. Has a {@code null} value in case table name is not provided.
41 | */
42 | private String tableName;
43 |
44 | /**
45 | * Constructs a sql database description.
46 | *
47 | * @param url The url of the sql databasae.
48 | * @param user The user name to access the sql database.
49 | * @param password The password to access the sql database.
50 | * @param tableName The database table name.
51 | */
52 | public SqlDatabaseDescription(String url, String user, String password, String tableName) {
53 | this.url = url;
54 | this.user = user;
55 | this.password = password;
56 | this.tableName = tableName;
57 | }
58 |
59 | /**
60 | * Returns the url of the sql databasae.
61 | *
62 | * @return The url of the sql databasae.
63 | */
64 | public String getUrl() {
65 | return url;
66 | }
67 |
68 | /**
69 | * Returns the user name used to access the sql database.
70 | *
71 | * @return The user name used to access the sql database.
72 | *
73 | */
74 | public String getUser() {
75 | return user;
76 | }
77 |
78 | /**
79 | * Returns the password used to access the sql database.
80 | *
81 | * @return The password used to access the sql database.
82 | */
83 | public String getPassword() {
84 | return password;
85 | }
86 |
87 | /**
88 | * Sets the password.
89 | *
90 | * @param password The new password to set.
91 | */
92 | public void setPassword(String password) {
93 | this.password = password;
94 | }
95 |
96 | /**
97 | * Returns the database table name.
98 | *
99 | * @return The database table name.
100 | */
101 | public String getTableName() {
102 | return tableName;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/OutputType.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * Enumeration of the supported output formats for the data source.
19 | * This enumeration almost exactly correlates to the "out" parameter of the wire protocol, except
20 | * JSONP which is never explicitly specified in the "out" parameter.
21 | *
22 | * @author Nimrod T.
23 | */
24 | public enum OutputType {
25 | HTML("html"),
26 | JSON("json"),
27 | JSONP("jsonp"),
28 | CSV("csv"),
29 |
30 | /**
31 | * Output type value for tab-separated values encoded using UTF-16
32 | * little-endian with byte-order mark supported by Microsoft Excel.
33 | *
34 | * UTF-8 encoding used by {@link #CSV} output type is not supported by Excel.
35 | * The Unicode encoding understood by Excel is UTF-16 little-endian with
36 | * byte-order mark. Excel also does not support comma delimiter in UTF-16
37 | * encoded files, however, it supports tab delimiter.
38 | *
39 | * The default output filename for Excel should have a {@code .csv} extension in
40 | * spite of containing tab-separated values because Excel does not
41 | * automatically associate with files having {@code .tsv} extension.
42 | */
43 | TSV_EXCEL("tsv-excel");
44 |
45 | /**
46 | * The code used to encode the output type in the tqx parameter.
47 | */
48 | private String code;
49 |
50 | /**
51 | * Constructs a new instance of this class with the given code.
52 | *
53 | * @param code Used to encode the output type in the tqx parameter.
54 | */
55 | OutputType(String code) {
56 | this.code = code;
57 | }
58 |
59 | /**
60 | * Returns the code for this OutputType.
61 | *
62 | * @return The code for this OutputType.
63 | */
64 | public String getCode() {
65 | return code;
66 | }
67 |
68 | /**
69 | * Finds the OutputType that matches the given code.
70 | *
71 | * @param code The code to search for.
72 | *
73 | * @return The OutputType that matches the given code or null if none are found.
74 | */
75 | public static OutputType findByCode(String code) {
76 | for (OutputType t : values()) {
77 | if (t.code.equals(code)) {
78 | return t;
79 | }
80 | }
81 | return null;
82 | }
83 |
84 | /**
85 | * Returns the default OutputType.
86 | *
87 | * @return The default OutputType.
88 | */
89 | public static OutputType defaultValue() {
90 | return JSON;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/examples/src/java/SimpleExampleServlet.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import com.google.visualization.datasource.DataSourceServlet;
16 | import com.google.visualization.datasource.base.TypeMismatchException;
17 | import com.google.visualization.datasource.datatable.ColumnDescription;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.datatable.value.ValueType;
20 | import com.google.visualization.datasource.query.Query;
21 |
22 | import java.util.ArrayList;
23 |
24 | import javax.servlet.http.HttpServletRequest;
25 |
26 | /**
27 | * A demo servlet for serving a simple, constant data table.
28 | * This servlet extends DataSourceServlet.
29 | *
30 | * @author Nimrod T.
31 | */
32 | public class SimpleExampleServlet extends DataSourceServlet {
33 |
34 | @Override
35 | public DataTable generateDataTable(Query query, HttpServletRequest request) {
36 | // Create a data table.
37 | DataTable data = new DataTable();
38 | ArrayList cd = new ArrayList();
39 | cd.add(new ColumnDescription("name", ValueType.TEXT, "Animal name"));
40 | cd.add(new ColumnDescription("link", ValueType.TEXT, "Link to wikipedia"));
41 | cd.add(new ColumnDescription("population", ValueType.NUMBER, "Population size"));
42 | cd.add(new ColumnDescription("vegeterian", ValueType.BOOLEAN, "Vegetarian?"));
43 |
44 | data.addColumns(cd);
45 |
46 | // Fill the data table.
47 | try {
48 | data.addRowFromValues("Aye-aye", "http://en.wikipedia.org/wiki/Aye-aye", 100, true);
49 | data.addRowFromValues("Sloth", "http://en.wikipedia.org/wiki/Sloth", 300, true);
50 | data.addRowFromValues("Leopard", "http://en.wikipedia.org/wiki/Leopard", 50, false);
51 | data.addRowFromValues("Tiger", "http://en.wikipedia.org/wiki/Tiger", 80, false);
52 | } catch (TypeMismatchException e) {
53 | System.out.println("Invalid type!");
54 | }
55 | return data;
56 | }
57 |
58 | /**
59 | * NOTE: By default, this function returns true, which means that cross
60 | * domain requests are rejected.
61 | * This check is disabled here so examples can be used directly from the
62 | * address bar of the browser. Bear in mind that this exposes your
63 | * data source to xsrf attacks.
64 | * If the only use of the data source url is from your application,
65 | * that runs on the same domain, it is better to remain in restricted mode.
66 | */
67 | @Override
68 | protected boolean isRestrictedAccessMode() {
69 | return false;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/engine/MetaTable.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.common.collect.Maps;
18 | import com.google.visualization.datasource.datatable.TableCell;
19 |
20 | import java.util.Map;
21 |
22 | /**
23 | * Holds the data of a table after pivoting and grouping, indexed by {@link RowTitle} and
24 | * {@link ColumnTitle}.
25 | *
26 | * @author Yonatan B.Y.
27 | */
28 | /* package */ class MetaTable {
29 |
30 | /**
31 | * The data. A map that gives, for each row and column, a map of the cell
32 | * associated with that row and that column.
33 | */
34 | private Map> data;
35 |
36 | /**
37 | * Creates an empty instance.
38 | */
39 | public MetaTable() {
40 | data = Maps.newHashMap();
41 | }
42 |
43 | /**
44 | * Puts a new value in the MetaTable.
45 | *
46 | * @param rowTitle The row into which the cell should be inserted.
47 | * @param columnTitle The column into which the cell should be inserted.
48 | * @param cell The cell to insert.
49 | */
50 | public void put(RowTitle rowTitle, ColumnTitle columnTitle,
51 | TableCell cell) {
52 | Map rowData = data.get(rowTitle);
53 | if (rowData == null) {
54 | rowData = Maps.newHashMap();
55 | data.put(rowTitle, rowData);
56 | }
57 | rowData.put(columnTitle, cell);
58 | }
59 |
60 | /**
61 | * Retrieves a cell from the MetaTable.
62 | *
63 | * @param rowTitle The row from which to retrieve the cell.
64 | * @param columnTitle The column from which to retrieve the cell.
65 | *
66 | * @return The cell that is at row rowTitle and column columnTitle or null
67 | * if no such cell exists.
68 | */
69 | public TableCell getCell(RowTitle rowTitle, ColumnTitle columnTitle) {
70 | Map rowData = data.get(rowTitle);
71 | if (rowData == null) {
72 | return null;
73 | }
74 | return rowData.get(columnTitle);
75 | }
76 |
77 | /**
78 | * Retrieves an entire row, in the form of a hashtable that maps a ColumnTitle
79 | * to a TableCell.
80 | *
81 | * @param rowTitle The title of the row to retrieve.
82 | *
83 | * @return The row.
84 | */
85 | public Map getRow(RowTitle rowTitle) {
86 | return data.get(rowTitle);
87 | }
88 |
89 | /**
90 | * Returns true if this MetaTable is empty, i.e., contains no rows.
91 | *
92 | * @return True if this MetaTable is empty.
93 | */
94 | public boolean isEmpty() {
95 | return data.isEmpty();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/base/ResponseStatusTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | import junit.framework.TestCase;
18 |
19 | import java.util.Locale;
20 |
21 | /**
22 | * Unit test for ResponseStatus.
23 | *
24 | * @author Nimrod T.
25 | */
26 | public class ResponseStatusTest extends TestCase {
27 | public void testBasic() {
28 | // Test getMessageForReasonType with default locale.
29 | assertEquals("Invalid query", ReasonType.INVALID_QUERY.getMessageForReasonType());
30 |
31 | // Test getMessageForReasonType with specified locale.
32 | assertEquals("Retrieved data was truncated",
33 | ReasonType.DATA_TRUNCATED.getMessageForReasonType(new Locale("en", "US")));
34 | }
35 |
36 | public void testGetModifiedResponseStatus() {
37 | String urlMessage = "http://www.google.com";
38 | ResponseStatus responseStatusAccessDenied = new ResponseStatus(StatusType.ERROR,
39 | ReasonType.ACCESS_DENIED, urlMessage);
40 | ResponseStatus responseStatusUserNotAuthenticated = new ResponseStatus(StatusType.ERROR,
41 | ReasonType.USER_NOT_AUTHENTICATED, urlMessage);
42 | ResponseStatus responseStatusUserNotAuthenticatedNoUrl = new ResponseStatus(StatusType.ERROR,
43 | ReasonType.USER_NOT_AUTHENTICATED, "123");
44 |
45 | // no modification
46 | assertEquals(responseStatusAccessDenied,
47 | ResponseStatus.getModifiedResponseStatus(responseStatusAccessDenied));
48 |
49 | assertEquals(responseStatusUserNotAuthenticatedNoUrl,
50 | ResponseStatus.getModifiedResponseStatus(responseStatusUserNotAuthenticatedNoUrl));
51 |
52 | // modified
53 | ResponseStatus modifiedResponse =
54 | ResponseStatus.getModifiedResponseStatus(responseStatusUserNotAuthenticated);
55 | assertEquals(StatusType.ERROR, modifiedResponse.getStatusType());
56 | assertEquals(ReasonType.USER_NOT_AUTHENTICATED, modifiedResponse.getReasonType());
57 | String htmlSignInString = "Sign in";
58 | assertEquals(htmlSignInString, modifiedResponse.getDescription());
59 | }
60 |
61 | public void testCreateResponseStatus() {
62 | DataSourceException dse = new DataSourceException(ReasonType.INTERNAL_ERROR, "123");
63 | ResponseStatus responseStatus = ResponseStatus.createResponseStatus(dse);
64 |
65 | assertEquals(StatusType.ERROR, responseStatus.getStatusType());
66 | assertEquals(ReasonType.INTERNAL_ERROR, responseStatus.getReasonType());
67 | assertEquals("123", responseStatus.getDescription());
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/ScalarFunction.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.Value;
19 | import com.google.visualization.datasource.datatable.value.ValueType;
20 |
21 | import java.util.List;
22 |
23 | /**
24 | * A scalar function.
25 | * A scalar function can have any arity, including 0, and can also have dynamic arity.
26 | * It must always produce a single value. The return type of such a function may depend on the
27 | * number and types of its arguments but never on their values. An instance of a class that
28 | * implements this interface can be used within a ScalarFunctionColumn.
29 | *
30 | * @author Liron L.
31 | */
32 | public interface ScalarFunction {
33 |
34 | /**
35 | * Returns the function's name.
36 | *
37 | * @return The function's name.
38 | */
39 | String getFunctionName();
40 |
41 | /**
42 | * Executes the scalar function on the given list of values, and returns the
43 | * Value which is the result of the execution the function.
44 | *
45 | * @param values The given list of parameter values for the scalar function.
46 | *
47 | * @return A Value which is the result of the executing the function.
48 | */
49 | Value evaluate(List values);
50 |
51 | /**
52 | * Returns the return type of the function, given specific types for its parameters. Some
53 | * functions can be polymorphic, i.e., their return type changes according to the types of their
54 | * parameters.
55 | *
56 | * @param types A list of the types of the function's parameters.
57 | *
58 | * @return The return type of the function.
59 | */
60 | ValueType getReturnType(List types);
61 |
62 | /**
63 | * Validates that the number and types of the function parameters are valid.
64 | * Throws an exception if they are not valid.
65 | *
66 | * @param types The given types of the function's parameters.
67 | *
68 | * @throws InvalidQueryException Thrown when the parameters are invalid.
69 | */
70 | void validateParameters(List types) throws InvalidQueryException;
71 |
72 | /**
73 | * Returns a string that when given to the query parser will yield a similar scalar function.
74 | * Takes as arguments the query strings of the arguments.
75 | *
76 | * @param argumentQueryStrings The query strings of the actual arguments.
77 | *
78 | * @return The query string.
79 | */
80 | String toQueryString(List argumentQueryStrings);
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/ColumnColumnFilterTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.visualization.datasource.datatable.ColumnDescription;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.datatable.TableCell;
20 | import com.google.visualization.datasource.datatable.TableRow;
21 | import com.google.visualization.datasource.datatable.value.ValueType;
22 |
23 | import junit.framework.TestCase;
24 |
25 |
26 | /**
27 | * Test for ColumnColumnFilter
28 | *
29 | * @author Yonatan B.Y.
30 | */
31 | public class ColumnColumnFilterTest extends TestCase {
32 | public void testMatch() {
33 | TableRow row = new TableRow();
34 | row.addCell(new TableCell("a"));
35 | row.addCell(new TableCell(123));
36 | row.addCell(new TableCell("a"));
37 |
38 | DataTable table = new DataTable();
39 | table.addColumn(new ColumnDescription("c1", ValueType.TEXT, "c1"));
40 | table.addColumn(new ColumnDescription("c2", ValueType.TEXT, "c2"));
41 | table.addColumn(new ColumnDescription("c3", ValueType.TEXT, "c3"));
42 |
43 | ColumnColumnFilter filter = new ColumnColumnFilter(new SimpleColumn("c1"),
44 | new SimpleColumn("c3"), ComparisonFilter.Operator.LE);
45 | assertTrue(filter.isMatch(table, row));
46 | }
47 |
48 | public void testNoMatch() {
49 | TableRow row = new TableRow();
50 | row.addCell(new TableCell("a"));
51 | row.addCell(new TableCell(123));
52 | row.addCell(new TableCell("a"));
53 |
54 | DataTable table = new DataTable();
55 | table.addColumn(new ColumnDescription("c1", ValueType.TEXT, "c1"));
56 | table.addColumn(new ColumnDescription("c2", ValueType.TEXT, "c2"));
57 | table.addColumn(new ColumnDescription("c3", ValueType.TEXT, "c3"));
58 |
59 | ColumnColumnFilter filter = new ColumnColumnFilter(new SimpleColumn("c3"),
60 | new SimpleColumn("c1"), ComparisonFilter.Operator.NE);
61 | assertFalse(filter.isMatch(table, row));
62 | }
63 |
64 | public void testToQueryString() {
65 | ColumnColumnFilter filter1 = new ColumnColumnFilter(new SimpleColumn("c3"),
66 | new AggregationColumn(new SimpleColumn("c4"), AggregationType.AVG),
67 | ComparisonFilter.Operator.NE);
68 | ColumnColumnFilter filter2 = new ColumnColumnFilter(
69 | new AggregationColumn(new SimpleColumn("c4"), AggregationType.SUM),
70 | new SimpleColumn("c1"), ComparisonFilter.Operator.STARTS_WITH);
71 |
72 | assertEquals("`c3` != AVG(`c4`)", filter1.toQueryString());
73 | assertEquals("SUM(`c4`) STARTS WITH `c1`", filter2.toQueryString());
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/examples/src/java/SqlDataSourceServlet.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import com.google.visualization.datasource.Capabilities;
16 | import com.google.visualization.datasource.DataSourceServlet;
17 | import com.google.visualization.datasource.base.DataSourceException;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.query.Query;
20 | import com.google.visualization.datasource.util.SqlDataSourceHelper;
21 | import com.google.visualization.datasource.util.SqlDatabaseDescription;
22 |
23 | import javax.servlet.http.HttpServletRequest;
24 |
25 | /**
26 | * An example data source servlet that can query an SQL database.
27 | * This makes use of the SqlDataSourceHelper class that is part of this library.
28 | *
29 | * Query language operations affect the result. This includes operations
30 | * that are not part of SQL itself, such as pivoting, which is executed by
31 | * the query engine.
32 | *
33 | * Four URL parameters must be specified, these are then passed to
34 | * the underlying SQL DB. The parameters are as follows:
35 | * url - The url of the sql DB.
36 | * user - The username to use when accessing the DB.
37 | * password - The password to use when accessing the DB.
38 | * table - The SQL table name.
39 | *
40 | * @author Yaniv S.
41 | */
42 | public class SqlDataSourceServlet extends DataSourceServlet {
43 |
44 | /**
45 | * The SQL predefined capabilities set is a special custom set for SQL
46 | * databases. This implements most of the data source capabilities more
47 | * efficiently.
48 | */
49 | @Override
50 | public Capabilities getCapabilities() {
51 | return Capabilities.SQL;
52 | }
53 |
54 | @Override
55 | public DataTable generateDataTable(Query query, HttpServletRequest request)
56 | throws DataSourceException {
57 | SqlDatabaseDescription dbDescription = new SqlDatabaseDescription(
58 | request.getParameter("url"),
59 | request.getParameter("user"),
60 | request.getParameter("password"),
61 | request.getParameter("table"));
62 | return SqlDataSourceHelper.executeQuery(query, dbDescription);
63 | }
64 |
65 | /**
66 | * NOTE: By default, this function returns true, which means that cross
67 | * domain requests are rejected.
68 | * This check is disabled here so examples can be used directly from the
69 | * address bar of the browser. Bear in mind that this exposes your
70 | * data source to xsrf attacks.
71 | * If the only use of the data source url is from your application,
72 | * that runs on the same domain, it is better to remain in restricted mode.
73 | */
74 | @Override
75 | protected boolean isRestrictedAccessMode() {
76 | return false;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/ColumnValueFilterTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.visualization.datasource.datatable.ColumnDescription;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.datatable.TableCell;
20 | import com.google.visualization.datasource.datatable.TableRow;
21 | import com.google.visualization.datasource.datatable.value.DateValue;
22 | import com.google.visualization.datasource.datatable.value.NumberValue;
23 | import com.google.visualization.datasource.datatable.value.TextValue;
24 | import com.google.visualization.datasource.datatable.value.ValueType;
25 |
26 | import junit.framework.TestCase;
27 |
28 |
29 | /**
30 | * Test for ColumnValueFilter
31 | *
32 | * @author Yonatan B.Y.
33 | */
34 | public class ColumnValueFilterTest extends TestCase {
35 |
36 | public void testVariousFilters() {
37 | TableRow row = new TableRow();
38 | row.addCell(new TableCell("a"));
39 | row.addCell(new TableCell(123));
40 | row.addCell(new TableCell("a"));
41 |
42 | DataTable table = new DataTable();
43 | table.addColumn(new ColumnDescription("c1", ValueType.TEXT, "c1"));
44 | table.addColumn(new ColumnDescription("c2", ValueType.TEXT, "c2"));
45 | table.addColumn(new ColumnDescription("c3", ValueType.TEXT, "c3"));
46 |
47 | ColumnValueFilter filter = new ColumnValueFilter(new SimpleColumn("c2"),
48 | new NumberValue(100), ComparisonFilter.Operator.GE);
49 | assertTrue(filter.isMatch(table, row));
50 | filter = new ColumnValueFilter(new SimpleColumn("c2"),
51 | new NumberValue(100), ComparisonFilter.Operator.LE, true);
52 | assertTrue(filter.isMatch(table, row));
53 | filter = new ColumnValueFilter(new SimpleColumn("c2"),
54 | new NumberValue(100), ComparisonFilter.Operator.LE);
55 | assertFalse(filter.isMatch(table, row));
56 | filter = new ColumnValueFilter(new SimpleColumn("c1"),
57 | new TextValue("b"), ComparisonFilter.Operator.GT);
58 | assertFalse(filter.isMatch(table, row));
59 | filter = new ColumnValueFilter(new SimpleColumn("c1"),
60 | new TextValue("b"), ComparisonFilter.Operator.LT, true);
61 | assertFalse(filter.isMatch(table, row));
62 | }
63 |
64 | public void testToQueryString() {
65 | ColumnValueFilter filter1 = new ColumnValueFilter(new SimpleColumn("c2"),
66 | new NumberValue(100.23), ComparisonFilter.Operator.GE);
67 | ColumnValueFilter filter2 = new ColumnValueFilter(
68 | new AggregationColumn(new SimpleColumn("c3"), AggregationType.MAX),
69 | new DateValue(2007, 2, 3), ComparisonFilter.Operator.LIKE, true);
70 |
71 | assertEquals("`c2` >= 100.23", filter1.toQueryString());
72 | assertEquals("DATE '2007-3-3' LIKE MAX(`c3`)", filter2.toQueryString());
73 |
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/scalarfunction/ToDateTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.common.collect.Lists;
18 | import com.google.visualization.datasource.base.InvalidQueryException;
19 | import com.google.visualization.datasource.datatable.value.DateTimeValue;
20 | import com.google.visualization.datasource.datatable.value.DateValue;
21 | import com.google.visualization.datasource.datatable.value.NumberValue;
22 | import com.google.visualization.datasource.datatable.value.Value;
23 | import com.google.visualization.datasource.datatable.value.ValueType;
24 |
25 | import junit.framework.TestCase;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * Tests for the ToDate scalar function.
31 | *
32 | * @author Liron L.
33 | */
34 | public class ToDateTest extends TestCase {
35 | public void testValidateParameters() throws InvalidQueryException {
36 | ToDate toDate = ToDate.getInstance();
37 |
38 | // Validate datetime, date, number and string paremeters.
39 | toDate.validateParameters(Lists.newArrayList(ValueType.DATETIME));
40 | toDate.validateParameters(Lists.newArrayList(ValueType.DATE));
41 | toDate.validateParameters(Lists.newArrayList(ValueType.NUMBER));
42 |
43 | // Should throw an exception.
44 | try {
45 | toDate.validateParameters(Lists.newArrayList(ValueType.TIMEOFDAY));
46 | fail("Should have thrown a ScalarFunctionException: The toDiff "
47 | + "function was given a timeofday parameter to validate.");
48 | } catch (InvalidQueryException e) {
49 | // Expected behavior.
50 | }
51 |
52 | // Should throw an exception.
53 | try {
54 | toDate.validateParameters(Lists.newArrayList(ValueType.DATE,
55 | ValueType.NUMBER));
56 | fail("Should have thrown a ScalarFunctionException: The toDAte "
57 | + "function was given 2 parameters.");
58 | } catch (InvalidQueryException e) {
59 | // Expected behavior.
60 | }
61 | }
62 |
63 | public void testEvaluate() {
64 | ToDate toDate = ToDate.getInstance();
65 | List valuesList1 =
66 | Lists.newArrayList(new DateValue(2008, 1, 13));
67 | List valuesList2 =
68 | Lists.newArrayList(
69 | new DateTimeValue(2008, 2, 23, 9, 12, 22, 333));
70 | List valuesList3 =
71 | Lists.newArrayList(new NumberValue(1234567890000.53421423424));
72 | List valuesList4 =
73 | Lists.newArrayList(new NumberValue(-1234567890000.0));
74 | assertEquals(new DateValue(2008, 1, 13), toDate.evaluate(valuesList1));
75 | assertEquals(new DateValue(2008, 2, 23), toDate.evaluate(valuesList2));
76 | assertEquals(new DateValue(2009, 1, 13), toDate.evaluate(valuesList3));
77 | assertEquals(new DateValue(1930, 10, 18), toDate.evaluate(valuesList4));
78 |
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/examples/src/html/all_examples.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | All Examples
5 |
6 |
7 |
78 |
79 |
80 |
Hello! Data Source!
81 | A pie chart to show the population of a group of animals.
82 | The data is taken from the simple data source.
83 |
84 | Use this toolbar to get the data in CSV/HTML.
85 |
86 |
87 |
CSV Data Source
88 | An organization chart.
89 | The data is taken from the csv data source.
90 |
91 |
92 |
Advanced Data Source
93 | A bar chart to show planetary masses.
94 | The data is taken from the advanced data source.
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/engine/ColumnValueAggregatorTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.visualization.datasource.datatable.value.DateValue;
18 | import com.google.visualization.datasource.datatable.value.NumberValue;
19 | import com.google.visualization.datasource.datatable.value.TextValue;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 | import com.google.visualization.datasource.query.AggregationType;
22 |
23 | import junit.framework.TestCase;
24 |
25 | /**
26 | * Tests for ColumnValueAggregator.java.
27 | *
28 | * @author Yoav G.
29 | */
30 |
31 | public class ColumnValueAggregatorTest extends TestCase {
32 |
33 | /**
34 | * Test all functionalities by aggregating two numbers.
35 | */
36 | public void testNumberAggregation() {
37 | ValueAggregator aggregator = new ValueAggregator(ValueType.NUMBER);
38 | aggregator.aggregate(new NumberValue(1));
39 | aggregator.aggregate(new NumberValue(3));
40 |
41 | assertEquals(new NumberValue(4.0), aggregator.getValue(AggregationType.SUM));
42 | assertEquals(new NumberValue(2.0), aggregator.getValue(AggregationType.AVG));
43 | assertEquals(new NumberValue(2), aggregator.getValue(AggregationType.COUNT));
44 | assertEquals(new NumberValue(1.0), aggregator.getValue(AggregationType.MIN));
45 | assertEquals(new NumberValue(3.0), aggregator.getValue(AggregationType.MAX));
46 | }
47 |
48 | /**
49 | * Test string aggregation.
50 | */
51 | public void testStringAggregation() {
52 | ValueAggregator aggregator = new ValueAggregator(ValueType.TEXT);
53 | aggregator.aggregate(new TextValue("a"));
54 | aggregator.aggregate(new TextValue("b"));
55 |
56 | try {
57 | aggregator.getValue(AggregationType.SUM);
58 | fail();
59 | } catch (UnsupportedOperationException e) {
60 | // Expected behavior.
61 | }
62 | try {
63 | aggregator.getValue(AggregationType.AVG);
64 | fail();
65 | } catch (UnsupportedOperationException e) {
66 | // Expected behavior.
67 | }
68 |
69 | assertEquals(new NumberValue(2), aggregator.getValue(AggregationType.COUNT));
70 | assertEquals(new TextValue("a"), aggregator.getValue(AggregationType.MIN));
71 | assertEquals(new TextValue("b"), aggregator.getValue(AggregationType.MAX));
72 |
73 | }
74 |
75 | public void testGetValueFromEmptyAggregation() {
76 | ValueAggregator aggregator = new ValueAggregator(ValueType.DATE);
77 | DateValue dateNull = DateValue.getNullValue();
78 | NumberValue numberNull = NumberValue.getNullValue();
79 |
80 | assertEquals(new NumberValue(0), aggregator.getValue(AggregationType.COUNT));
81 |
82 | assertEquals(dateNull, aggregator.getValue(AggregationType.MIN));
83 | assertEquals(dateNull, aggregator.getValue(AggregationType.MAX));
84 |
85 | assertEquals(numberNull, aggregator.getValue(AggregationType.AVG));
86 | assertEquals(numberNull, aggregator.getValue(AggregationType.SUM));
87 | }
88 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/parser/QueryBuilder.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.parser;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.base.MessagesEnum;
19 | import com.google.visualization.datasource.query.Query;
20 |
21 | import com.ibm.icu.util.ULocale;
22 |
23 | import org.apache.commons.lang.StringUtils;
24 | import org.apache.commons.logging.Log;
25 | import org.apache.commons.logging.LogFactory;
26 |
27 |
28 | /**
29 | * A singleton class that can parse a user query string, i.e., accept a string such as
30 | * "SELECT dept, max(salary) GROUP BY dept" and return a Query object. This class basically
31 | * wraps the QueryParser class that is auto-generated from the QueryParser.jj specification.
32 | *
33 | * @author Hillel M.
34 | */
35 | public class QueryBuilder {
36 |
37 | /**
38 | * Log.
39 | */
40 | private static final Log log = LogFactory.getLog(QueryBuilder.class.getName());
41 |
42 | /**
43 | * A singleton instance of this class.
44 | */
45 | private static final QueryBuilder SINGLETON = new QueryBuilder();
46 |
47 | /**
48 | * Returns the singleton instance of this class.
49 | *
50 | * @return The singleton query builder.
51 | */
52 | public static QueryBuilder getInstance() {
53 | return SINGLETON;
54 | }
55 |
56 | /**
57 | * Private constructor, to prevent instantiation other than that of the singleton instance.
58 | */
59 | private QueryBuilder() {
60 | }
61 |
62 | /**
63 | * Parses a user query into a Query object.
64 | *
65 | * @param tqValue The user query string.
66 | *
67 | * @return The parsed Query object.
68 | *
69 | * @throws InvalidQueryException Thrown if the query is invalid.
70 | */
71 | public Query parseQuery(String tqValue) throws InvalidQueryException {
72 | return parseQuery(tqValue, null);
73 | }
74 |
75 | /**
76 | * Parses a user query into a Query object.
77 | *
78 | * @param tqValue The user query string.
79 | * @param ulocale The user locale.
80 | *
81 | * @return The parsed Query object.
82 | *
83 | * @throws InvalidQueryException Thrown if the query is invalid.
84 | */
85 | public Query parseQuery(String tqValue, ULocale ulocale) throws InvalidQueryException {
86 | Query query;
87 | if (StringUtils.isEmpty(tqValue)) {
88 | query = new Query();
89 | } else {
90 | try {
91 | query = QueryParser.parseString(tqValue);
92 | } catch (ParseException ex) {
93 | String messageToUserAndLog = ex.getMessage();
94 | log.error("Parsing error: " + messageToUserAndLog);
95 | throw new InvalidQueryException(MessagesEnum.PARSE_ERROR.getMessageWithArgs(ulocale,
96 | messageToUserAndLog));
97 | }
98 | query.setLocaleForUserMessages(ulocale);
99 | query.validate();
100 | }
101 | return query;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/CurrentDateTime.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.DateTimeValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import com.ibm.icu.util.GregorianCalendar;
23 | import com.ibm.icu.util.TimeZone;
24 |
25 | import java.util.List;
26 |
27 | /**
28 | * A 0-ary function that returns the current datetime. The return type is always DateTime.
29 | *
30 | * @author Liron L.
31 | */
32 | public class CurrentDateTime implements ScalarFunction {
33 |
34 | /**
35 | * The name of this function.
36 | */
37 | private static final String FUNCTION_NAME = "now";
38 |
39 | /**
40 | * A singleton instance of this class.
41 | */
42 | private static final CurrentDateTime INSTANCE = new CurrentDateTime();
43 |
44 | /**
45 | * Private constructor, to prevent instantiation other than by the singleton.
46 | */
47 | private CurrentDateTime() {}
48 |
49 | /**
50 | * Returns the singleton instance of this class.
51 | *
52 | * @return The singleton instance of this class.
53 | */
54 | public static CurrentDateTime getInstance() {
55 | return INSTANCE;
56 | }
57 |
58 | /**
59 | * {@inheritDoc}
60 | */
61 | public String getFunctionName() {
62 | return FUNCTION_NAME;
63 | }
64 |
65 | /**
66 | * Evaluates this scalar function. Returns a DateTime with the current time.
67 | *
68 | * @param values Ignored.
69 | *
70 | * @return A DateTime value with the current time.
71 | */
72 | public Value evaluate(List values) {
73 | return new DateTimeValue(new GregorianCalendar(
74 | TimeZone.getTimeZone("GMT")));
75 | }
76 |
77 | /**
78 | * Returns the return type of the function. In this case, DATETIME.
79 | *
80 | * @param types Ignored.
81 | *
82 | * @return The type of the returned value: DATETIME.
83 | */
84 | public ValueType getReturnType(List types) {
85 | return ValueType.DATETIME;
86 | }
87 |
88 | /**
89 | * Validates that there are no parameters given for the function. Throws a
90 | * ScalarFunctionException otherwise.
91 | *
92 | * @param types A list with parameters types. Should be empty for this type of function.
93 | *
94 | * @throws InvalidQueryException Thrown if the parameters are invalid.
95 | */
96 | public void validateParameters(List types)
97 | throws InvalidQueryException {
98 | if (types.size() != 0) {
99 | throw new InvalidQueryException("The " + FUNCTION_NAME + " function should not get "
100 | + "any parameters");
101 | }
102 | }
103 |
104 | /**
105 | * {@inheritDoc}
106 | */
107 | public String toQueryString(List argumentsQueryStrings) {
108 | return FUNCTION_NAME + "()";
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/test/java/com/google/visualization/datasource/query/scalarfunction/DateDiffTest.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.common.collect.Lists;
18 | import com.google.visualization.datasource.base.InvalidQueryException;
19 | import com.google.visualization.datasource.datatable.value.DateTimeValue;
20 | import com.google.visualization.datasource.datatable.value.DateValue;
21 | import com.google.visualization.datasource.datatable.value.NumberValue;
22 | import com.google.visualization.datasource.datatable.value.Value;
23 | import com.google.visualization.datasource.datatable.value.ValueType;
24 |
25 | import junit.framework.TestCase;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * Tests for the DateDiff scalar function.
31 | *
32 | * @author Liron L.
33 | */
34 | public class DateDiffTest extends TestCase {
35 | public void testValidateParameters() throws InvalidQueryException {
36 | List types = Lists.newArrayList(ValueType.DATE,
37 | ValueType.DATETIME);
38 | DateDiff dateDiff = DateDiff.getInstance();
39 |
40 | // Validate date paremeter.
41 | dateDiff.validateParameters(types);
42 |
43 | // Should throw an exception.
44 | try {
45 | dateDiff.validateParameters(Lists.newArrayList(ValueType.DATE,
46 | ValueType.NUMBER));
47 | fail("Should have thrown a ScalarFunctionException: The dateDiff "
48 | + "function was given a number parameter to validate.");
49 | } catch (InvalidQueryException e) {
50 | // do nothing
51 | }
52 |
53 | // Validate datetime paremeter.
54 | types = Lists.newArrayList(ValueType.DATETIME, ValueType.DATETIME);
55 | dateDiff.validateParameters(types);
56 |
57 | // Should throw an exception.
58 | try {
59 | dateDiff.validateParameters(Lists.newArrayList(ValueType.DATE));
60 | fail("Should have thrown a ScalarFunctionException: The dateDiff "
61 | + "function was given only 1 parameter.");
62 | } catch (InvalidQueryException e) {
63 | // Expected behavior.
64 | }
65 | }
66 |
67 | public void testEvaluate() {
68 | DateDiff dateDiff = DateDiff.getInstance();
69 | List valuesList1 =
70 | Lists.newArrayList(new DateValue(2008, 1, 13),
71 | new DateValue(2008, 2, 13));
72 | List valuesList2 = Lists.newArrayList(new DateValue(2008, 1, 13),
73 | new DateTimeValue(2008, 1, 13, 9, 12, 22, 333));
74 | List valuesList3 =
75 | Lists.newArrayList(new DateTimeValue(2008, 6, 1, 9, 12, 22, 333),
76 | new DateTimeValue(2008, 10, 1, 9, 12, 22, 333));
77 | List valuesList4 = Lists.newArrayList(new DateTimeValue(
78 | 2008, 10, 1, 9, 12, 22, 333),
79 | new DateTimeValue(2008, 6, 1, 9, 12, 20, 333));
80 |
81 | assertEquals(new NumberValue(-29), dateDiff.evaluate(valuesList1));
82 | assertEquals(new NumberValue(0), dateDiff.evaluate(valuesList2));
83 | assertEquals(new NumberValue(-123), dateDiff.evaluate(valuesList3));
84 | assertEquals(new NumberValue(123), dateDiff.evaluate(valuesList4));
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Constant.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.Value;
19 | import com.google.visualization.datasource.datatable.value.ValueType;
20 |
21 | import java.util.List;
22 |
23 | /**
24 | * A constant function, i.e., a 0-ary function that always returns the same value, given at
25 | * construction time. The value can be of any supported {@link ValueType}.
26 | *
27 | * @author Liron L.
28 | */
29 | public class Constant implements ScalarFunction {
30 |
31 | /**
32 | * The value of this constant.
33 | */
34 | private Value value;
35 |
36 | /**
37 | * Constructs a new constant function that always returns the given value.
38 | *
39 | * @param value The value to constantly return.
40 | */
41 | public Constant(Value value) {
42 | this.value = value;
43 | }
44 |
45 | /**
46 | * {@inheritDoc}
47 | */
48 | public String getFunctionName() {
49 | return value.toQueryString();
50 | }
51 |
52 | /**
53 | * Executes the scalar function constant(). The values parameter is ignored.
54 | * Returns the value supplied at construction time.
55 | *
56 | * @param values Ignored.
57 | *
58 | * @return The value supplied at construction time.
59 | */
60 | public Value evaluate(List values) {
61 | return value;
62 | }
63 |
64 | /**
65 | * Returns the return type of the function. This matches the type of the value
66 | * supplied at construction time. The types parameter is ignored.
67 | *
68 | * @param types Ignored.
69 | *
70 | * @return The return type of this function.
71 | */
72 | public ValueType getReturnType(List types) {
73 | return value.getType();
74 | }
75 |
76 | /**
77 | * Validates that there are no parameters given for the function. Throws a
78 | * ScalarFunctionException otherwise.
79 | *
80 | * @param types A list with parameters types. Should be empty for this type of function.
81 | *
82 | * @throws InvalidQueryException Thrown if the parameters are invalid.
83 | */
84 | public void validateParameters(List types)
85 | throws InvalidQueryException {
86 | if (types.size() != 0) {
87 | throw new InvalidQueryException("The constant function should not get "
88 | + "any parameters");
89 | }
90 | }
91 |
92 | @Override
93 | public boolean equals(Object o) {
94 | if (o instanceof Constant) {
95 | Constant other = (Constant) o;
96 | return value.equals(other.value);
97 | }
98 | return false;
99 | }
100 |
101 | @Override
102 | public int hashCode() {
103 | return (value == null) ? 0 : value.hashCode();
104 | }
105 |
106 | /**
107 | * {@inheritDoc}
108 | */
109 | public String toQueryString(List argumentsQueryStrings) {
110 | return value.toQueryString();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.google
7 | google
8 | 1
9 |
10 | com.google.visualization
11 | visualization-datasource
12 | Google Visualization Data Source Library
13 | 1.1.2
14 | This library makes it easy to implement a Visualization data source so that you can
15 | easily chart or visualize your data from any of your data stores.
16 | The library implements the Google Visualization API wire protocol and query language.
17 | You therefore need write only the code required to make your data available to the library in
18 | the form of a data table.
19 | This task is made easier by the provision of abstract classes and helper
20 | functions.
21 |
22 | UTF-8
23 |
24 |
25 |
26 | commons-lang
27 | commons-lang
28 | 2.4
29 |
30 |
31 | commons-logging
32 | commons-logging
33 | 1.1.1
34 |
35 |
36 | com.google.guava
37 | guava
38 | r07
39 |
40 |
41 | com.ibm.icu
42 | icu4j
43 | 4.0.1
44 |
45 |
46 | net.sf.opencsv
47 | opencsv
48 | 1.8
49 |
50 |
51 | javax.servlet
52 | servlet-api
53 | 2.5
54 | provided
55 |
56 |
57 | junit
58 | junit
59 | 4.6
60 | test
61 |
62 |
63 | org.easymock
64 | easymock
65 | 2.5
66 | test
67 |
68 |
69 |
70 | ${basedir}/build
71 | ${basedir}/build/class/main
72 | ${basedir}/build/class/test
73 |
74 |
75 |
76 | org.apache.maven.plugins
77 | maven-compiler-plugin
78 |
79 | 1.6
80 | 1.6
81 |
82 |
83 |
84 | org.codehaus.mojo
85 | javacc-maven-plugin
86 | 2.5
87 |
88 |
89 | javacc
90 |
91 | javacc
92 |
93 |
94 | ${basedir}/src/main/java
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/engine/TableRowComparator.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.engine;
16 |
17 | import com.google.visualization.datasource.datatable.TableRow;
18 | import com.google.visualization.datasource.datatable.value.Value;
19 | import com.google.visualization.datasource.query.AbstractColumn;
20 | import com.google.visualization.datasource.query.ColumnLookup;
21 | import com.google.visualization.datasource.query.ColumnSort;
22 | import com.google.visualization.datasource.query.QuerySort;
23 | import com.google.visualization.datasource.query.SortOrder;
24 | import com.ibm.icu.util.ULocale;
25 |
26 | import java.util.Comparator;
27 | import java.util.List;
28 |
29 | /**
30 | * A comparator comparing two {@link TableRow}s according to the query's ORDER BY, i.e.,
31 | * {@link QuerySort}.
32 | *
33 | * @author Yoah B.D.
34 | */
35 | /*package*/ class TableRowComparator implements Comparator {
36 |
37 | /**
38 | * The columns to order by, in sequence of importance.
39 | */
40 | private AbstractColumn[] sortColumns;
41 |
42 | /**
43 | * The sort order of the columns to order by, in sequence of importance. Will
44 | * be of same size as sortColumnIndex.
45 | */
46 | private SortOrder[] sortColumnOrder;
47 |
48 | /**
49 | * A value comparator.
50 | */
51 | private Comparator valueComparator;
52 |
53 | /**
54 | * The column lookup.
55 | */
56 | private ColumnLookup columnLookup;
57 |
58 | /**
59 | * Construct a new TableRowComparator.
60 | *
61 | * @param sort The ordering criteria.
62 | * @param locale The locale defining the order relation of text values.
63 | * @param lookup The column lookup.
64 | */
65 | public TableRowComparator(QuerySort sort, ULocale locale, ColumnLookup lookup) {
66 | valueComparator = Value.getLocalizedComparator(locale);
67 | columnLookup = lookup;
68 | List columns = sort.getSortColumns();
69 | sortColumns = new AbstractColumn[columns.size()];
70 | sortColumnOrder = new SortOrder[columns.size()];
71 | for (int i = 0; i < columns.size(); i++) {
72 | ColumnSort columnSort = columns.get(i);
73 | sortColumns[i] = columnSort.getColumn();
74 | sortColumnOrder[i] = columnSort.getOrder();
75 | }
76 | }
77 |
78 | /**
79 | * Compares two arguments for order. Returns a negative integer, zero, or
80 | * a positive integer if the first argument is less than, equal to, or greater
81 | * than the second.
82 | *
83 | * @param r1 the first row to be compared.
84 | * @param r2 the second row to be compared.
85 | *
86 | * @return a negative integer, zero, or a positive integer as the first
87 | * argument is less than, equal to, or greater than the second.
88 | */
89 | public int compare(TableRow r1, TableRow r2) {
90 | for (int i = 0; i < sortColumns.length; i++) {
91 | AbstractColumn col = sortColumns[i];
92 | int cc = valueComparator.compare(col.getValue(columnLookup, r1),
93 | col.getValue(columnLookup, r2));
94 | if (cc != 0) {
95 | return (sortColumnOrder[i] == SortOrder.ASCENDING) ? cc : -cc;
96 | }
97 | }
98 | return 0;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/datatable/value/NumberValue.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable.value;
16 |
17 | /**
18 | * A value of type number. Valid values are double-precision floating-point numbers
19 | * (including integers) or NULL_VALUE.
20 | *
21 | * @author Yoah B.D.
22 | */
23 | public class NumberValue extends Value {
24 |
25 | /**
26 | * A single static null value.
27 | */
28 | private static final NumberValue NULL_VALUE = new NumberValue(-9999);
29 |
30 | /**
31 | * Static method to return the null value (same one for all calls).
32 | * @return Null value.
33 | */
34 | public static NumberValue getNullValue() {
35 | return NULL_VALUE;
36 | }
37 |
38 | /**
39 | * The underlying value.
40 | */
41 | private double value;
42 |
43 | /**
44 | * Create a new number value.
45 | *
46 | * @param value The underlying value.
47 | */
48 | public NumberValue(double value) {
49 | this.value = value;
50 | }
51 |
52 | @Override
53 | public ValueType getType() {
54 | return ValueType.NUMBER;
55 | }
56 |
57 | /**
58 | * Returns the underlying value.
59 | *
60 | * @return The underlying value.
61 | */
62 | public double getValue() {
63 | if (this == NULL_VALUE) {
64 | throw new NullValueException("This null number has no value");
65 | }
66 | return value;
67 | }
68 |
69 | /**
70 | * Returns the number as a String using default formatting.
71 | *
72 | * @return The number as a String using default formatting.
73 | */
74 | @Override
75 | public String toString() {
76 | if (this == NULL_VALUE) {
77 | return "null";
78 | }
79 | return Double.toString(value);
80 | }
81 |
82 | /**
83 | * Tests whether this value is a logical null.
84 | *
85 | * @return Indication of whether the value is null.
86 | */
87 | @Override
88 | public boolean isNull() {
89 | return (this == NULL_VALUE);
90 | }
91 |
92 | /**
93 | * Compares this value to another value of the same type.
94 | *
95 | * @param other Other value.
96 | *
97 | * @return 0 if equal, negative if this is smaller, positive if larger.
98 | */
99 | @Override
100 | public int compareTo(Value other) {
101 | if (this == other) {
102 | return 0; // If same value, or both are null.
103 | }
104 | NumberValue otherNumber = (NumberValue) other;
105 | if (isNull()) {
106 | return -1;
107 | }
108 | if (otherNumber.isNull()) {
109 | return 1;
110 | }
111 | return Double.compare(value, otherNumber.value);
112 | }
113 |
114 | /**
115 | * Returns a hash code for this number value.
116 | *
117 | * @return A hash code for this number value.
118 | */
119 | @Override
120 | public int hashCode() {
121 | if (isNull()) {
122 | return 0;
123 | }
124 | return new Double(value).hashCode();
125 | }
126 |
127 | @Override
128 | public Number getObjectToFormat() {
129 | if (isNull()) {
130 | return null;
131 | }
132 | return value;
133 | }
134 |
135 | /**
136 | * {@inheritDoc}
137 | */
138 | @Override
139 | protected String innerToQueryString() {
140 | return Double.toString(value);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/QueryOptions.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | /**
18 | * Options definition for a query.
19 | * Holds options for the query that fall under the options clause.
20 | *
21 | * @author Yonatan B.Y.
22 | */
23 | public class QueryOptions {
24 |
25 | /**
26 | * Should be set to indicate not to return the values, but only the column
27 | * labels and types (table description).
28 | */
29 | private boolean noValues;
30 |
31 | /**
32 | * Should be set to indicate not to format the values, but to return only the
33 | * raw data. By default returns both raw and formatted values.
34 | */
35 | private boolean noFormat;
36 |
37 | /**
38 | * Constructs query options with all boolean options set to false.
39 | */
40 | public QueryOptions() {
41 | noValues = false;
42 | noFormat = false;
43 | }
44 |
45 | /**
46 | * Returns the value of the noValues option.
47 | *
48 | * @return The value of the noValues option.
49 | */
50 | public boolean isNoValues() {
51 | return noValues;
52 | }
53 |
54 | /**
55 | * Sets the value of the noValues option.
56 | *
57 | * @param noValues The new value of the noValues option.
58 | */
59 | public void setNoValues(boolean noValues) {
60 | this.noValues = noValues;
61 | }
62 |
63 | /**
64 | * Returns the value of the noFormat option.
65 | *
66 | * @return The value of the noFormat option.
67 | */
68 | public boolean isNoFormat() {
69 | return noFormat;
70 | }
71 |
72 | /**
73 | * Sets the value of the noFormat option.
74 | *
75 | * @param noFormat The new value of the noFormat option.
76 | */
77 | public void setNoFormat(boolean noFormat) {
78 | this.noFormat = noFormat;
79 | }
80 |
81 | /**
82 | * Returns true if all options are set to their default values.
83 | *
84 | * @return True if all options are set to their default values.
85 | */
86 | public boolean isDefault() {
87 | return !noFormat && !noValues;
88 | }
89 |
90 | @Override
91 | public int hashCode() {
92 | final int prime = 31;
93 | int result = 1;
94 | result = prime * result + (noFormat ? 1231 : 1237);
95 | result = prime * result + (noValues ? 1231 : 1237);
96 | return result;
97 | }
98 |
99 | @Override
100 | public boolean equals(Object obj) {
101 | if (this == obj) {
102 | return true;
103 | }
104 | if (obj == null) {
105 | return false;
106 | }
107 | if (getClass() != obj.getClass()) {
108 | return false;
109 | }
110 | QueryOptions other = (QueryOptions) obj;
111 | if (noFormat != other.noFormat) {
112 | return false;
113 | }
114 | if (noValues != other.noValues) {
115 | return false;
116 | }
117 | return true;
118 | }
119 |
120 | /**
121 | * Returns a string that when fed to the query parser should return a QueryOptions equal to this
122 | * one. Used mainly for debugging purposes. The string returned does not contain the
123 | * OPTIONS keyword.
124 | *
125 | * @return The query string.
126 | */
127 | public String toQueryString() {
128 | return (noValues ? "NO_VALUES" : "") + (noFormat ? "NO_FORMAT" : "");
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/ColumnIsNullFilter.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.common.collect.Sets;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.datatable.TableRow;
20 |
21 | import java.util.List;
22 | import java.util.Set;
23 |
24 | /**
25 | * A filter that matches null values. Its isMatch function returns true if
26 | * the value at the column is a null value (as defined by TableCell.isNull()).
27 | *
28 | * @author Yonatan B.Y.
29 | */
30 | public class ColumnIsNullFilter extends QueryFilter {
31 |
32 | /**
33 | * The ID of the column that should be null.
34 | */
35 | private AbstractColumn column;
36 |
37 | /**
38 | * Constructs a new instance of this class with the given column ID.
39 | *
40 | * @param column The column that should be null.
41 | */
42 | public ColumnIsNullFilter(AbstractColumn column) {
43 | this.column = column;
44 | }
45 |
46 | /**
47 | * Returns the column that should be null.
48 | *
49 | * @return The column that should be null.
50 | */
51 | public AbstractColumn getColumn() {
52 | return column;
53 | }
54 |
55 | /**
56 | * {@inheritDoc}
57 | */
58 | @Override
59 | public Set getAllColumnIds() {
60 | return Sets.newHashSet(column.getAllSimpleColumnIds());
61 | }
62 |
63 | /**
64 | * Returns a list of all scalarFunctionColumns this filter uses, in this case
65 | * the scalarFunctionColumns in column (e.g, in the filter 'year(a) is null'
66 | * it will return year(a).
67 | *
68 | * @return A list of all scalarFunctionColumns this filter uses.
69 | */
70 | @Override
71 | public List getScalarFunctionColumns() {
72 | return column.getAllScalarFunctionColumns();
73 | }
74 |
75 | /**
76 | * {@inheritDoc}
77 | */
78 | @Override
79 | protected List getAggregationColumns() {
80 | return column.getAllAggregationColumns();
81 | }
82 |
83 | /**
84 | * {@inheritDoc}
85 | */
86 | @Override
87 | public boolean isMatch(DataTable table, TableRow row) {
88 | DataTableColumnLookup lookup = new DataTableColumnLookup(table);
89 | return column.getValue(lookup, row).isNull();
90 | }
91 |
92 | /**
93 | * {@inheritDoc}
94 | */
95 | @Override
96 | public String toQueryString() {
97 | return column.toQueryString() + " IS NULL";
98 | }
99 |
100 | @Override
101 | public int hashCode() {
102 | final int prime = 31;
103 | int result = 1;
104 | result = prime * result + ((column == null) ? 0 : column.hashCode());
105 | return result;
106 | }
107 |
108 | @Override
109 | public boolean equals(Object obj) {
110 | if (this == obj) {
111 | return true;
112 | }
113 | if (obj == null) {
114 | return false;
115 | }
116 | if (getClass() != obj.getClass()) {
117 | return false;
118 | }
119 | ColumnIsNullFilter other = (ColumnIsNullFilter) obj;
120 | if (column == null) {
121 | if (other.column != null) {
122 | return false;
123 | }
124 | } else if (!column.equals(other.column)) {
125 | return false;
126 | }
127 | return true;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/NegationFilter.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.visualization.datasource.datatable.DataTable;
18 | import com.google.visualization.datasource.datatable.TableRow;
19 |
20 | import java.util.List;
21 | import java.util.Set;
22 |
23 | /**
24 | * A negation filter.
25 | * Holds a sub-filter and negates its result, acting like the NOT operator.
26 | *
27 | * @author Yonatan B.Y.
28 | */
29 | public class NegationFilter extends QueryFilter {
30 |
31 | /**
32 | * The sub-filter of this negation filter.
33 | */
34 | private QueryFilter subFilter;
35 |
36 | /**
37 | * Constructs a negation filter, with the given sub-filter.
38 | *
39 | * @param subFilter The sub-filter of this negation filter.
40 | */
41 | public NegationFilter(QueryFilter subFilter) {
42 | this.subFilter = subFilter;
43 | }
44 |
45 | /**
46 | * Implements isMatch (from the QueryFilter interface) by recursively calling
47 | * isMatch on the sub-filter and negating the result.
48 | *
49 | * @param table The table containing this row.
50 | * @param row The row to check.
51 | *
52 | * @return true if this row should be part of the result set, false otherwise.
53 | */
54 | @Override
55 | public boolean isMatch(DataTable table, TableRow row) {
56 | return !subFilter.isMatch(table, row);
57 | }
58 |
59 | /**
60 | * Returns all the columnIds this filter uses, in this case exactly all the
61 | * columnIds that the sub-filter uses.
62 | *
63 | * @return All the columnIds this filter uses.
64 | */
65 | @Override
66 | public Set getAllColumnIds() {
67 | return subFilter.getAllColumnIds();
68 | }
69 |
70 | /**
71 | * Returns a list of all scalarFunctionColumns this filter uses, in this case
72 | * the scalarFunctionColumns its sub-filter uses.
73 | *
74 | * @return A list of all scalarFunctionColumns this filter uses.
75 | */
76 | @Override
77 | public List getScalarFunctionColumns() {
78 | return subFilter.getScalarFunctionColumns();
79 | }
80 |
81 | /**
82 | * {@InheritDoc}
83 | */
84 | @Override
85 | protected List getAggregationColumns() {
86 | return subFilter.getAggregationColumns();
87 | }
88 |
89 | /**
90 | * Returns the sub-filter associated with this NegationFilter.
91 | *
92 | * @return The sub-filter associated with this NegationFilter.
93 | */
94 | public QueryFilter getSubFilter() {
95 | return subFilter;
96 | }
97 |
98 | /**
99 | * {@inheritDoc}
100 | */
101 | @Override
102 | public String toQueryString() {
103 | return "NOT (" + subFilter.toQueryString() + ")";
104 | }
105 |
106 | @Override
107 | public int hashCode() {
108 | final int prime = 31;
109 | int result = 1;
110 | result = prime * result + ((subFilter == null) ? 0 : subFilter.hashCode());
111 | return result;
112 | }
113 |
114 | @Override
115 | public boolean equals(Object obj) {
116 | if (this == obj) {
117 | return true;
118 | }
119 | if (obj == null) {
120 | return false;
121 | }
122 | if (getClass() != obj.getClass()) {
123 | return false;
124 | }
125 | NegationFilter other = (NegationFilter) obj;
126 | if (subFilter == null) {
127 | if (other.subFilter != null) {
128 | return false;
129 | }
130 | } else if (!subFilter.equals(other.subFilter)) {
131 | return false;
132 | }
133 | return true;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/SimpleColumn.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.common.collect.Lists;
18 | import com.google.visualization.datasource.datatable.DataTable;
19 | import com.google.visualization.datasource.datatable.value.ValueType;
20 |
21 | import java.util.List;
22 |
23 | /**
24 | * A column referred to by an explicit string ID.
25 | *
26 | * @author Yonatan B.Y.
27 | */
28 | public class SimpleColumn extends AbstractColumn {
29 |
30 | /**
31 | * The explicit string ID of the column.
32 | */
33 | private String columnId;
34 |
35 | /**
36 | * Creates a new instance of this class, with the given column ID.
37 | *
38 | * @param columnId The column ID.
39 | */
40 | public SimpleColumn(String columnId) {
41 | this.columnId = columnId;
42 | }
43 |
44 | /**
45 | * Returns the column ID.
46 | *
47 | * @return The column ID.
48 | */
49 | public String getColumnId() {
50 | return columnId;
51 | }
52 |
53 | @Override
54 | public String getId() {
55 | return columnId;
56 | }
57 |
58 | @Override
59 | public List getAllSimpleColumnIds() {
60 | return Lists.newArrayList(columnId);
61 | }
62 |
63 | @Override
64 | public boolean equals(Object o) {
65 | if (o instanceof SimpleColumn) {
66 | SimpleColumn other = (SimpleColumn) o;
67 | return columnId.equals(other.columnId);
68 | }
69 | return false;
70 | }
71 |
72 | @Override
73 | public int hashCode() {
74 | int hash = 1279; // Some arbitrary prime number.
75 | hash = (hash * 17) + columnId.hashCode();
76 | return hash;
77 | }
78 |
79 | @Override
80 | public String toString() {
81 | return columnId;
82 | }
83 |
84 | /**
85 | * Returns a list of all simple columns. In this case, returns only itself.
86 | *
87 | * @return A list of all simple columns.
88 | */
89 | @Override
90 | public List getAllSimpleColumns() {
91 | return Lists.newArrayList(this);
92 | }
93 |
94 | /**
95 | * Returns a list of all aggregation columns. In this case, returns an empty
96 | * list.
97 | *
98 | * @return A list of all aggregation columns.
99 | */
100 | @Override
101 | public List getAllAggregationColumns() {
102 | return Lists.newArrayList();
103 | }
104 |
105 | /**
106 | * Returns a list of all scalar function columns. In this case, returns an
107 | * empty list.
108 | *
109 | * @return A list of all scalar function columns.
110 | */
111 | @Override
112 | public List getAllScalarFunctionColumns() {
113 | return Lists.newArrayList();
114 | }
115 |
116 | /**
117 | * Checks if the column is valid. In this case always does nothing.
118 | *
119 | * @param dataTable The data table.
120 | */
121 | @Override
122 | public void validateColumn(DataTable dataTable) {
123 | }
124 |
125 | /**
126 | * Returns the value type of the column. In this case returns the value type
127 | * of the column itself.
128 | *
129 | * @param dataTable The data table.
130 | *
131 | * @return the value type of the column.
132 | */
133 | @Override
134 | public ValueType getValueType(DataTable dataTable) {
135 | return dataTable.getColumnDescription(columnId).getType();
136 | }
137 |
138 | @Override
139 | public String toQueryString() {
140 | if (columnId.contains("`")) {
141 | throw new RuntimeException("Column ID cannot contain backtick (`)");
142 | }
143 | return "`" + columnId + "`";
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Sum.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.NumberValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * The binary scalar function sum().
26 | * Returns the sum of two number values.
27 | *
28 | * @author Liron L.
29 | */
30 | public class Sum implements ScalarFunction {
31 |
32 | /**
33 | * The name of this function.
34 | */
35 | private static final String FUNCTION_NAME = "sum";
36 |
37 | /**
38 | * A singleton instance of this class.
39 | */
40 | private static final Sum INSTANCE = new Sum();
41 |
42 | /**
43 | * A private constructor, to prevent instantiation other than by the singleton.
44 | */
45 | private Sum() {}
46 |
47 | /**
48 | * Returns the singleton instance of this class.
49 | *
50 | * @return The singleton instance of this class.
51 | */
52 | public static Sum getInstance() {
53 | return INSTANCE;
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | public String getFunctionName() {
60 | return FUNCTION_NAME;
61 | }
62 |
63 | /**
64 | * Executes the scalar function sum() on the given values. Returns the sum of
65 | * the given values. All values are number values.
66 | * The method does not validate the parameters, the user must check the
67 | * parameters before calling this method.
68 | *
69 | * @param values A list of values on which the scalar function is performed.
70 | *
71 | * @return Value with the sum of all given values, or number null value if one
72 | * of the values is null.
73 | */
74 | public Value evaluate(List values) {
75 | if (values.get(0).isNull() || values.get(1).isNull()) {
76 | return NumberValue.getNullValue();
77 | }
78 | double sum = ((NumberValue) values.get(0)).getValue() +
79 | ((NumberValue) values.get(1)).getValue();
80 | return new NumberValue(sum);
81 | }
82 |
83 | /**
84 | * Returns the return type of the function. In this case, NUMBER. The method
85 | * does not validate the parameters, the user must check the parameters
86 | * before calling this method.
87 | *
88 | * @param types A list of the types of the scalar function parameters.
89 | *
90 | * @return The type of the returned value: Number.
91 | */
92 | public ValueType getReturnType(List types) {
93 | return ValueType.NUMBER;
94 | }
95 |
96 | /**
97 | * Validates that all function parameters are of type NUMBER, and that there
98 | * are exactly 2 parameters. Throws a ScalarFunctionException otherwise.
99 | *
100 | * @param types A list of parameter types.
101 | *
102 | * @throws InvalidQueryException Thrown if the parameters are invalid.
103 | */
104 | public void validateParameters(List types) throws InvalidQueryException {
105 | if (types.size() != 2) {
106 | throw new InvalidQueryException("The function " + FUNCTION_NAME
107 | + " requires 2 parmaeters ");
108 | }
109 | for (ValueType type : types) {
110 | if (type != ValueType.NUMBER) {
111 | throw new InvalidQueryException("Can't perform the function "
112 | + FUNCTION_NAME + " on values that are not numbers");
113 | }
114 | }
115 | }
116 |
117 | /**
118 | * {@inheritDoc}
119 | */
120 | public String toQueryString(List argumentsQueryStrings) {
121 | return "(" + argumentsQueryStrings.get(0) + " + " + argumentsQueryStrings.get(1) + ")";
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Product.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.NumberValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * The binary scalar function product().
26 | * Returns the product of two number values.
27 | *
28 | * @author Liron L.
29 | */
30 | public class Product implements ScalarFunction {
31 |
32 | /**
33 | * The name of this function.
34 | */
35 | private static final String FUNCTION_NAME = "product";
36 |
37 | /**
38 | * A singleton instance of this class.
39 | */
40 | private static final Product INSTANCE = new Product();
41 |
42 | /**
43 | * A private constructor, to prevent instantiation other than by the singleton.
44 | */
45 | private Product() {}
46 |
47 | /**
48 | * Returns the singleton instance of this class.
49 | *
50 | * @return The singleton instance of this class.
51 | */
52 | public static Product getInstance() {
53 | return INSTANCE;
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | public String getFunctionName() {
60 | return FUNCTION_NAME;
61 | }
62 |
63 | /**
64 | * Executes the scalar function product() on the given values. Returns the
65 | * product of the given values. All values are number values.
66 | * The method does not validate the parameters, the user must check the
67 | * parameters before calling this method.
68 | *
69 | * @param values A list of values on which the scalar function is performed.
70 | *
71 | * @return Value with the product of all given values, or number null value
72 | * if one of the values is null.
73 | */
74 | public Value evaluate(List values) {
75 | if (values.get(0).isNull() || values.get(1).isNull()) {
76 | return NumberValue.getNullValue();
77 | }
78 | double product = ((NumberValue) values.get(0)).getValue() *
79 | ((NumberValue) values.get(1)).getValue();
80 | return new NumberValue(product);
81 | }
82 |
83 | /**
84 | * Returns the return type of the function. In this case, NUMBER. The method
85 | * does not validate the parameters, the user must check the parameters
86 | * before calling this method.
87 | *
88 | * @param types A list of the types of the scalar function parameters.
89 | *
90 | * @return The type of the returned value: Number.
91 | */
92 | public ValueType getReturnType(List types) {
93 | return ValueType.NUMBER;
94 | }
95 |
96 | /**
97 | * Validates that all function parameters are of type NUMBER, and that there
98 | * are exactly 2 parameters. Throws a ScalarFunctionException otherwise.
99 | *
100 | * @param types A list with parameters types.
101 | *
102 | * @throws InvalidQueryException Thrown if the parameters are invalid.
103 | */
104 | public void validateParameters(List types) throws InvalidQueryException {
105 | if (types.size() != 2) {
106 | throw new InvalidQueryException("The function " + FUNCTION_NAME
107 | + " requires 2 parmaeters ");
108 | }
109 | for (ValueType type : types) {
110 | if (type != ValueType.NUMBER) {
111 | throw new InvalidQueryException("Can't perform the function "
112 | + FUNCTION_NAME + " on values that are not numbers");
113 | }
114 | }
115 | }
116 |
117 | /**
118 | * {@inheritDoc}
119 | */
120 | public String toQueryString(List argumentsQueryStrings) {
121 | return "(" + argumentsQueryStrings.get(0) + " * " + argumentsQueryStrings.get(1) + ")";
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Difference.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.NumberValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * The binary scalar function difference().
27 | * Returns the difference between two number values.
28 | *
29 | * @author Liron L.
30 | */
31 | public class Difference implements ScalarFunction {
32 |
33 | /**
34 | * The name of this function.
35 | */
36 | private static final String FUNCTION_NAME = "difference";
37 |
38 | /**
39 | * A singleton instance of this class.
40 | */
41 | private static final Difference INSTANCE = new Difference();
42 |
43 | /**
44 | * A private constructor.
45 | */
46 | private Difference() {}
47 |
48 | /**
49 | * Returns the singleton instance of this class.
50 | *
51 | * @return The singleton instance of this class.
52 | */
53 | public static Difference getInstance() {
54 | return INSTANCE;
55 | }
56 |
57 | /**
58 | * {@inheritDoc}
59 | */
60 | public String getFunctionName() {
61 | return FUNCTION_NAME;
62 | }
63 |
64 | /**
65 | * Executes the scalar function difference() on the given values. Returns the
66 | * difference between the given values. All values are number values.
67 | * The method does not validate the parameters, the user must check the
68 | * parameters before calling this method.
69 | *
70 | * @param values A list of the values on which the scalar function will be performed.
71 | *
72 | * @return Value with the difference of all given values, or number null value
73 | * if one of the values is null.
74 | */
75 | public Value evaluate(List values) {
76 | if (values.get(0).isNull() || values.get(1).isNull()) {
77 | return NumberValue.getNullValue();
78 | }
79 | double difference = ((NumberValue) values.get(0)).getValue() -
80 | ((NumberValue) values.get(1)).getValue();
81 | return new NumberValue(difference);
82 | }
83 |
84 | /**
85 | * Returns the return type of the function. In this case, NUMBER. The method
86 | * does not validate the parameters, the user must check the parameters
87 | * before calling this method.
88 | *
89 | * @param types A list of the types of the scalar function parameters.
90 | *
91 | * @return The type of the returned value: Number.
92 | */
93 | public ValueType getReturnType(List types) {
94 | return ValueType.NUMBER;
95 | }
96 |
97 | /**
98 | * Validates that all function parameters are of type NUMBER, and that there
99 | * are exactly 2 parameters. Throws a ScalarFunctionException otherwise.
100 | *
101 | * @param types A list with parameters types.
102 | *
103 | * @throws InvalidQueryException Thrown if the parameters are invalid.
104 | */
105 | public void validateParameters(List types) throws InvalidQueryException {
106 | if (types.size() != 2) {
107 | throw new InvalidQueryException("The function " + FUNCTION_NAME
108 | + " requires 2 parmaeters ");
109 | }
110 | for (ValueType type : types) {
111 | if (type != ValueType.NUMBER) {
112 | throw new InvalidQueryException("Can't perform the function "
113 | + FUNCTION_NAME + " on values that are not numbers");
114 | }
115 | }
116 | }
117 |
118 | /**
119 | * {@inheritDoc}
120 | */
121 | public String toQueryString(List argumentsQueryStrings) {
122 | return "(" + argumentsQueryStrings.get(0) + " - " + argumentsQueryStrings.get(1) + ")";
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Modulo.java:
--------------------------------------------------------------------------------
1 | // Copyright 2010 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.NumberValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * The binary scalar function modulo().
26 | * Returns the modulo between two number values.
27 | *
28 | * @author Roee E.
29 | */
30 | public class Modulo implements ScalarFunction {
31 |
32 | /**
33 | * The name of this function.
34 | */
35 | private static final String FUNCTION_NAME = "modulo";
36 |
37 | /**
38 | * A singleton instance of this class.
39 | */
40 | private static final Modulo INSTANCE = new Modulo();
41 |
42 | /**
43 | * A private constructor, to prevent instantiation other than by the singleton.
44 | */
45 | private Modulo() {}
46 |
47 | /**
48 | * Returns the singleton instance of this class.
49 | *
50 | * @return The singleton instance of this class.
51 | */
52 | public static Modulo getInstance() {
53 | return INSTANCE;
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | public String getFunctionName() {
60 | return FUNCTION_NAME;
61 | }
62 |
63 | /**
64 | * Executes a binary scalar function modulo() between the first and the second
65 | * values in the list. Returns the modulo between the given values. All values
66 | * are number values. The method does not validate the parameters,
67 | * the user must check the parameters before calling this method.
68 | *
69 | * @param values A list of values on which the scalar function is performed.
70 | *
71 | *
72 | * @return Value with the modulo between two given values, or number null value
73 | * if one of the values is null.
74 | */
75 | public Value evaluate(List values) {
76 | if (values.get(0).isNull() || values.get(1).isNull()) {
77 | return NumberValue.getNullValue();
78 | }
79 | double modulo = ((NumberValue) values.get(0)).getValue() %
80 | ((NumberValue) values.get(1)).getValue();
81 | return new NumberValue(modulo);
82 | }
83 |
84 | /**
85 | * Returns the return type of the function. In this case, NUMBER. The method
86 | * does not validate the parameters, the user must check the parameters
87 | * before calling this method.
88 | *
89 | * @param types A list of the types of the scalar function parameters.
90 | *
91 | * @return The type of the returned value: Number.
92 | */
93 | public ValueType getReturnType(List types) {
94 | return ValueType.NUMBER;
95 | }
96 |
97 | /**
98 | * Validates that all function parameters are of type NUMBER, and that there
99 | * are exactly 2 parameters. Throws a ScalarFunctionException otherwise.
100 | *
101 | * @param types A list with parameters types.
102 | *
103 | * @throws InvalidQueryException Thrown if the parameters are invalid.
104 | */
105 | public void validateParameters(List types) throws InvalidQueryException {
106 | if (types.size() != 2) {
107 | throw new InvalidQueryException("The function " + FUNCTION_NAME
108 | + " requires 2 parmaeters ");
109 | }
110 | for (ValueType type : types) {
111 | if (type != ValueType.NUMBER) {
112 | throw new InvalidQueryException("Can't perform the function "
113 | + FUNCTION_NAME + " on values that are not numbers");
114 | }
115 | }
116 | }
117 |
118 | /**
119 | * {@inheritDoc}
120 | */
121 | public String toQueryString(List argumentsQueryStrings) {
122 | return "(" + argumentsQueryStrings.get(0) + " % " + argumentsQueryStrings.get(1) + ")";
123 | }
124 | }
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/datatable/value/TextValue.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable.value;
16 |
17 | import com.ibm.icu.text.Collator;
18 | import com.ibm.icu.util.ULocale;
19 |
20 | import java.util.Comparator;
21 |
22 | /**
23 | * A value of type text (string).
24 | *
25 | * @author Yoah B.D.
26 | */
27 | public class TextValue extends Value {
28 |
29 | /**
30 | * A single static null value.
31 | */
32 | private static final TextValue NULL_VALUE = new TextValue("");
33 |
34 | /**
35 | * The underlying value.
36 | */
37 | private String value;
38 |
39 | /**
40 | * Creates a new text cell.
41 | *
42 | * @param value The cell's value.
43 | */
44 | public TextValue(String value) {
45 | if (value == null) {
46 | throw new NullPointerException("Cannot create a text value from null.");
47 | }
48 | this.value = value;
49 | }
50 |
51 | @Override
52 | public ValueType getType() {
53 | return ValueType.TEXT;
54 | }
55 |
56 | /**
57 | * Returns the text.
58 | *
59 | * @return The underlying text.
60 | */
61 | @Override
62 | public String toString() {
63 | return value;
64 | }
65 |
66 | /**
67 | * Static method to return the null value (same one for all calls).
68 | *
69 | * @return Null value.
70 | */
71 | public static TextValue getNullValue() {
72 | return NULL_VALUE;
73 | }
74 |
75 | /**
76 | * Tests whether this cell's value is logical null.
77 | *
78 | * @return Indication of whether the cell's value is null.
79 | */
80 | @Override
81 | public boolean isNull() {
82 | return (this == NULL_VALUE);
83 | }
84 |
85 | /**
86 | * Compares this value to another value of the same type.
87 | *
88 | * @param other Other value.
89 | *
90 | * @return 0 if equal, negative if this is smaller, positive if larger.
91 | */
92 | @Override
93 | public int compareTo(Value other) {
94 | if (this == other) {
95 | return 0;
96 | }
97 | // TextValue has no NULL_VALUE.
98 | return value.compareTo(((TextValue) other).value);
99 | }
100 |
101 | /**
102 | * Returns a hash code for this string value.
103 | *
104 | * @return A hash code for this string value.
105 | */
106 | @Override
107 | public int hashCode() {
108 | // TextValue has no NULL_VALUE.
109 | return value.hashCode();
110 | }
111 |
112 | @Override
113 | public String getObjectToFormat() {
114 | return value;
115 | }
116 |
117 | /**
118 | * Returns a comparator that compares text values according to a given locale.
119 | *
120 | * @param ulocale The ulocale defining the order relation for text values.
121 | *
122 | * @return A comparator that compares text values according to a given locale.
123 | */
124 | public static Comparator getTextLocalizedComparator(final ULocale ulocale) {
125 | return new Comparator() {
126 | Collator collator = Collator.getInstance(ulocale);
127 |
128 | @Override
129 | public int compare(TextValue tv1, TextValue tv2) {
130 | if (tv1 == tv2) {
131 | return 0;
132 | }
133 | return collator.compare(tv1.value, tv2.value);
134 | }
135 | };
136 | }
137 |
138 | /**
139 | * Returns the text value.
140 | *
141 | * @return The underlying text value.
142 | */
143 | public String getValue() {
144 | return value;
145 | }
146 |
147 | /**
148 | * {@inheritDoc}
149 | */
150 | @Override
151 | protected String innerToQueryString() {
152 | if (value.contains("\"")) {
153 | if (value.contains("'")) {
154 | throw new RuntimeException("Cannot run toQueryString() on string"
155 | + " values that contain both \" and '.");
156 | } else {
157 | return "'" + value + "'";
158 | }
159 | } else {
160 | return "\"" + value + "\"";
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/ErrorMessages.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | import java.util.ListResourceBundle;
18 |
19 | /**
20 | * A resource bundle that contains all the error messages for a datasource in the en-US locale.
21 | * This is the default locale used in this library.
22 | *
23 | * @author Yaniv S.
24 | */
25 | public class ErrorMessages extends ListResourceBundle {
26 |
27 | /**
28 | * The contents of this bundle. A key to message map.
29 | */
30 | static final Object[][] CONTENTS = {
31 | {"UNKNOWN_DATA_SOURCE_ID", "Unknown data source ID"},
32 | {"ACCESS_DENIED", "Access denied"},
33 | {"USER_NOT_AUTHENTICATED", "User not signed in"},
34 | {"UNSUPPORTED_QUERY_OPERATION", "Unsupported query operation"},
35 | {"INVALID_QUERY", "Invalid query"},
36 | {"INVALID_REQUEST", "Invalid request"},
37 | {"INTERNAL_ERROR", "Internal error"},
38 | {"NOT_SUPPORTED", "Operation not supported"},
39 | {"DATA_TRUNCATED", "Retrieved data was truncated"},
40 | {"NOT_MODIFIED", "Data not modified"},
41 | {"TIMEOUT", "Request timeout"},
42 | {"ILLEGAL_FORMATTING_PATTERNS", "Illegal formatting patterns"},
43 | {"OTHER", "Could not complete request"},
44 | {"SIGN_IN", "Sign in"},
45 | // QUERY Errors
46 | {"NO_COLUMN", "Column [{0}] does not exist in table."},
47 | {"AVG_SUM_ONLY_NUMERIC",
48 | "'Average' and 'sum' aggreagation functions can be applied only on numeric values."},
49 | {"INVALID_AGG_TYPE", "Invalid aggregation type: {0}"},
50 | // Parse
51 | {"PARSE_ERROR", "Query parse error: {0}"},
52 | {"CANNOT_BE_IN_GROUP_BY", "Column [{0}] cannot be in GROUP BY because it has an aggregation."},
53 | {"CANNOT_BE_IN_PIVOT", "Column [{0}] cannot be in PIVOT because it has an aggregation."},
54 | {"CANNOT_BE_IN_WHERE", "Column [{0}] cannot appear in WHERE because it has an aggregation."},
55 | {"SELECT_WITH_AND_WITHOUT_AGG",
56 | "Column [{0}] cannot be selected both with and without aggregation in SELECT."},
57 | {"COL_AGG_NOT_IN_SELECT",
58 | "Column [{0}] which is aggregated in SELECT, cannot appear in GROUP BY."},
59 | {"CANNOT_GROUP_WITNOUT_AGG", "Cannot use GROUP BY when no aggregations are defined in SELECT."},
60 | {"CANNOT_PIVOT_WITNOUT_AGG", "Cannot use PIVOT when no aggregations are defined in SELECT."},
61 | {"AGG_IN_SELECT_NO_PIVOT",
62 | "Column [{0}] which is aggregated in SELECT, cannot appear in PIVOT."},
63 | {"FORMAT_COL_NOT_IN_SELECT",
64 | "Column [{0}] which is referenced in FORMAT, is not part of SELECT clause."},
65 | {"LABEL_COL_NOT_IN_SELECT",
66 | "Column [{0}] which is referenced in LABEL, is not part of SELECT clause."},
67 | {"ADD_COL_TO_GROUP_BY_OR_AGG",
68 | "Column [{0}] should be added to GROUP BY, removed from SELECT, or aggregated in SELECT."},
69 | {"AGG_IN_ORDER_NOT_IN_SELECT",
70 | "Aggregation [{0}] found in ORDER BY but was not found in SELECT"},
71 | {"NO_AGG_IN_ORDER_WHEN_PIVOT",
72 | "Column [{0}] cannot be aggregated in ORDER BY when PIVOT is used."},
73 | {"COL_IN_ORDER_MUST_BE_IN_SELECT",
74 | "Column [{0}] which appears in ORDER BY, must be in SELECT as well, " +
75 | "because SELECT contains aggregated columns."},
76 | {"NO_COL_IN_GROUP_AND_PIVOT", "Column [{0}] cannot appear both in GROUP BY and in PIVOT."},
77 | {"INVALID_OFFSET", "Invalid value for row offset: {0}"},
78 | {"INVALID_SKIPPING", "Invalid value for row skipping: {0}"},
79 | {"COLUMN_ONLY_ONCE", "Column [{0}] cannot appear more than once in {1}."}
80 |
81 |
82 | };
83 |
84 | /**
85 | * Returns the error messages.
86 | * Note that this method exposes the inner array. This means it can be changed by the outside
87 | * world. We are not cloning here to avoid the computation time hit. Please do not change the
88 | * inner values unless you know what you are doing.
89 | */
90 | @Override
91 | public Object[][] getContents() {
92 | return CONTENTS;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/QueryPivot.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.common.collect.ImmutableList;
18 | import com.google.common.collect.Lists;
19 |
20 | import java.util.List;
21 |
22 | /**
23 | * Pivoting definition for a query.
24 | * Pivoting is defined as a list of column IDs to pivot.
25 | *
26 | * @author Yoav G.
27 | * @author Yonatan B.Y.
28 | */
29 | public class QueryPivot {
30 |
31 | /**
32 | * The list of pivot columns.
33 | */
34 | private List columns;
35 |
36 | /**
37 | * Constructs a query pivot with empty lists.
38 | */
39 | public QueryPivot() {
40 | columns = Lists.newArrayList();
41 | }
42 |
43 | /**
44 | * Adds a column to pivot.
45 | *
46 | * @param column The column to add.
47 | */
48 | public void addColumn(AbstractColumn column) {
49 | columns.add(column);
50 | }
51 |
52 | /**
53 | * Returns the list of pivot column IDs. This list is immutable.
54 | *
55 | * @return The list of pivot column IDs. This list is immutable.
56 | */
57 | public List getColumnIds() {
58 | List columnIds = Lists.newArrayList();
59 | for (AbstractColumn col : columns) {
60 | columnIds.add(col.getId());
61 | }
62 | return ImmutableList.copyOf(columnIds);
63 | }
64 |
65 | /**
66 | * Returns a list of all simple columns' IDs in this pivot.
67 | *
68 | * @return A list of all simple columns' IDs in this pivot.
69 | */
70 | public List getSimpleColumnIds() {
71 | List columnIds = Lists.newArrayList();
72 | for (AbstractColumn col : columns) {
73 | columnIds.addAll(col.getAllSimpleColumnIds());
74 | }
75 | return columnIds;
76 | }
77 |
78 | /**
79 | * Returns the list of pivot columns. This list is immutable.
80 | *
81 | * @return The list of pivot columns. This list is immutable.
82 | */
83 | public List getColumns() {
84 | return ImmutableList.copyOf(columns);
85 | }
86 |
87 | /**
88 | * Returns the list of pivot simple columns.
89 | *
90 | * @return The list of pivot simple columns.
91 | */
92 | public List getSimpleColumns() {
93 | List simpleColumns = Lists.newArrayList();
94 | for (AbstractColumn col : columns) {
95 | simpleColumns.addAll(col.getAllSimpleColumns());
96 | }
97 | return simpleColumns;
98 | }
99 |
100 | /**
101 | * Returns the list of pivot scalar function columns.
102 | *
103 | * @return The list of pivot scalar function columns.
104 | */
105 | public List getScalarFunctionColumns() {
106 | List scalarFunctionColumns = Lists.newArrayList();
107 | for (AbstractColumn col : columns) {
108 | scalarFunctionColumns.addAll(col.getAllScalarFunctionColumns());
109 | }
110 | return scalarFunctionColumns;
111 | }
112 |
113 | @Override
114 | public int hashCode() {
115 | final int prime = 31;
116 | int result = 1;
117 | result = prime * result + ((columns == null) ? 0 : columns.hashCode());
118 | return result;
119 | }
120 |
121 | @Override
122 | public boolean equals(Object obj) {
123 | if (this == obj) {
124 | return true;
125 | }
126 | if (obj == null) {
127 | return false;
128 | }
129 | if (getClass() != obj.getClass()) {
130 | return false;
131 | }
132 | QueryPivot other = (QueryPivot) obj;
133 | if (columns == null) {
134 | if (other.columns != null) {
135 | return false;
136 | }
137 | } else if (!columns.equals(other.columns)) {
138 | return false;
139 | }
140 | return true;
141 | }
142 |
143 | /**
144 | * Returns a string that when fed to the query parser would produce an equal QueryPivot.
145 | * The string is returned without the PIVOT keywors.
146 | *
147 | * @return The query string.
148 | */
149 | public String toQueryString() {
150 | return Query.columnListToQueryString(columns);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/scalarfunction/Quotient.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query.scalarfunction;
16 |
17 | import com.google.visualization.datasource.base.InvalidQueryException;
18 | import com.google.visualization.datasource.datatable.value.NumberValue;
19 | import com.google.visualization.datasource.datatable.value.Value;
20 | import com.google.visualization.datasource.datatable.value.ValueType;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * The binary scalar function quotient().
26 | * Returns the quotient of two values. Division by zero returns a null number
27 | * value.
28 | *
29 | * @author Liron L.
30 | */
31 | public class Quotient implements ScalarFunction {
32 |
33 | /**
34 | * The name of this function.
35 | */
36 | private static final String FUNCTION_NAME = "quotient";
37 |
38 | /**
39 | * A singleton instance of this class.
40 | */
41 | private static final Quotient INSTANCE = new Quotient();
42 |
43 | /**
44 | * A private constructor, to prevent instantiation other than by the singleton.
45 | */
46 | private Quotient() {}
47 |
48 | /**
49 | * Returns the singleton instance of this class.
50 | *
51 | * @return The singleton instance of this class.
52 | */
53 | public static Quotient getInstance() {
54 | return INSTANCE;
55 | }
56 |
57 | /**
58 | * {@inheritDoc}
59 | */
60 | public String getFunctionName() {
61 | return FUNCTION_NAME;
62 | }
63 |
64 | /**
65 | * Executes the scalar function quotient() on the given values. Returns the
66 | * quotient of the given values. All values are number values. Division by
67 | * zero returns a null number value.
68 | * The method does not validate the parameters, the user must check the
69 | * parameters before calling this method.
70 | *
71 | * @param values A list of values on which the scalar function is performed.
72 | *
73 | * @return Value with the quotient of all given values, or number null value
74 | * if one of the values is null or if one of the denominators is zero.
75 | */
76 | public Value evaluate(List values) {
77 | if (values.get(0).isNull() || values.get(1).isNull()
78 | || (((NumberValue) values.get(1)).getValue() == 0)) {
79 | return NumberValue.getNullValue();
80 | }
81 | double quotient = ((NumberValue) values.get(0)).getValue() /
82 | ((NumberValue) values.get(1)).getValue();
83 | return new NumberValue(quotient);
84 | }
85 |
86 | /**
87 | * Returns the return type of the function. In this case, NUMBER. The method
88 | * does not validate the parameters, the user must check the parameters
89 | * before calling this method.
90 | *
91 | * @param types A list of the types of the scalar function parameters.
92 | *
93 | * @return The type of the returned value: Number.
94 | */
95 | public ValueType getReturnType(List types) {
96 | return ValueType.NUMBER;
97 | }
98 |
99 | /**
100 | * Validates that all function parameters are of type NUMBER, and that there
101 | * are exactly 2 parameters. Throws a ScalarFunctionException otherwise.
102 | *
103 | * @param types A list with parameters types.
104 | *
105 | * @throws InvalidQueryException Thrown if the parameters are invalid.
106 | */
107 | public void validateParameters(List types) throws InvalidQueryException {
108 | if (types.size() != 2) {
109 | throw new InvalidQueryException("The function " + FUNCTION_NAME
110 | + " requires 2 parmaeters ");
111 | }
112 | for (ValueType type : types) {
113 | if (type != ValueType.NUMBER) {
114 | throw new InvalidQueryException("Can't perform the function "
115 | + FUNCTION_NAME + " on values that are not numbers");
116 | }
117 | }
118 | }
119 |
120 | /**
121 | * {@inheritDoc}
122 | */
123 | public String toQueryString(List argumentsQueryStrings) {
124 | return "(" + argumentsQueryStrings.get(0) + " / " + argumentsQueryStrings.get(1) + ")";
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/datatable/value/BooleanValue.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable.value;
16 |
17 | /**
18 | * A value of type boolean. Valid values are TRUE, FALSE and NULL_VALUE.
19 | *
20 | * @author Yoah B.D.
21 | */
22 | public class BooleanValue extends Value {
23 |
24 | /**
25 | * A single static null value.
26 | */
27 | private static final BooleanValue NULL_VALUE = new BooleanValue(false);
28 |
29 | /**
30 | * A single static TRUE value.
31 | */
32 | public static final BooleanValue TRUE = new BooleanValue(true);
33 |
34 | /**
35 | * A single static FALSE value.
36 | */
37 | public static final BooleanValue FALSE = new BooleanValue(false);
38 |
39 | /**
40 | * Static method to return the null value (same one for all calls)
41 | *
42 | * @return Null value.
43 | */
44 | public static BooleanValue getNullValue() {
45 | return NULL_VALUE;
46 | }
47 |
48 | /**
49 | * Static method to return a BooleanValue based on a given java boolean.
50 | * If the parameter is null, returns NULL_VALUE.
51 | *
52 | * @param value The java Boolean value to be represented.
53 | *
54 | * @return The static predefined instance of the given value.
55 | */
56 | public static BooleanValue getInstance(Boolean value) {
57 | if (value == null) {
58 | return NULL_VALUE;
59 | }
60 | return value ? TRUE : FALSE;
61 | }
62 |
63 | /**
64 | * The underlying value
65 | */
66 | private boolean value;
67 |
68 | /**
69 | * Create a new boolean value.
70 | * This is private so users must use the three predefined values here (Null,
71 | * true, and false), like an enum.
72 | *
73 | * @param value The underlying value.
74 | */
75 | private BooleanValue(boolean value) {
76 | this.value = value;
77 | }
78 |
79 | @Override
80 | public ValueType getType() {
81 | return ValueType.BOOLEAN;
82 | }
83 |
84 | /**
85 | * Returns the underlying value.
86 | *
87 | * @return The underlying value.
88 | */
89 | public boolean getValue() {
90 | if (this == NULL_VALUE) {
91 | throw new NullValueException("This null boolean has no value");
92 | }
93 | return value;
94 | }
95 |
96 | /**
97 | * Returns the value with default formatting.
98 | *
99 | * @return The value with default formatting.
100 | */
101 | @Override
102 | public String toString() {
103 | if (this == NULL_VALUE) {
104 | return "null";
105 | }
106 | return Boolean.toString(value);
107 | }
108 |
109 | /**
110 | * Tests whether this cell's value is a logical null.
111 | *
112 | * @return Indication if the call's value is null.
113 | */
114 | @Override
115 | public boolean isNull() {
116 | return (this == NULL_VALUE);
117 | }
118 |
119 | /**
120 | * Compares this cell to another cell of the same type.
121 | *
122 | * @param other Other cell.
123 | *
124 | * @return 0 if equal, negative if this is smaller, positive if larger.
125 | */
126 | @Override
127 | public int compareTo(Value other) {
128 | if (this == other) {
129 | return 0; // If same cell, or both are null.
130 | }
131 | BooleanValue otherBoolean = (BooleanValue) other;
132 | if (isNull()) {
133 | return -1;
134 | }
135 | if (otherBoolean.isNull()) {
136 | return 1;
137 | }
138 | return (value == otherBoolean.value ? 0 : (value ? 1 : -1));
139 | }
140 |
141 | /**
142 | * Returns a hash code for this boolean value.
143 | *
144 | * @return A hash code for this boolean value. Null gets -1, false gets 0,
145 | * true gets 1.
146 | */
147 | @Override
148 | public int hashCode() {
149 | return (isNull() ? -1 : (value ? 1 : 0));
150 | }
151 |
152 |
153 | @Override
154 | public Boolean getObjectToFormat() {
155 | if (isNull()) {
156 | return null;
157 | }
158 | return value;
159 | }
160 |
161 | /**
162 | * {@inheritDoc}
163 | */
164 | @Override
165 | protected String innerToQueryString() {
166 | return value ? "true" : "false";
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/base/ResponseStatus.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.base;
16 |
17 | /**
18 | * A response status holds three parameters:
19 | * 1) The response type (Ok, Warning or Error).
20 | * 2) The response reason type.
21 | * 3) A string with an error message to the user.
22 | *
23 | * @author Hillel M.
24 | */
25 | public class ResponseStatus {
26 |
27 | /**
28 | * The response status type.
29 | */
30 | private StatusType statusType;
31 |
32 | /**
33 | * The response reason type (if OK or ERROR).
34 | */
35 | private ReasonType reasonType;
36 |
37 | /**
38 | * A message to be passed to the user (if ERROR).
39 | */
40 | private String description;
41 |
42 | /**
43 | * The sign in message key in the ResourceBundle
44 | */
45 | public static final String SIGN_IN_MESSAGE_KEY = "SIGN_IN";
46 |
47 | /**
48 | * Constructs a response status object.
49 | * This object contains a status type, reason type,
50 | * and a message that is sent to the user.
51 | *
52 | * @param statusType The response status type.
53 | * @param reasonType The response reason type.
54 | * @param description A message to be passed to the user.
55 | */
56 | public ResponseStatus(StatusType statusType, ReasonType reasonType, String description) {
57 | this.statusType = statusType;
58 | this.reasonType = reasonType;
59 | this.description = description;
60 | }
61 |
62 | /**
63 | * Creates a ResponseStatus for the given DataSourceException.
64 | *
65 | * @param dse The data source exception.
66 | *
67 | * @return A response status object for the given data source exception.
68 | */
69 | public static ResponseStatus createResponseStatus(DataSourceException dse) {
70 | return new ResponseStatus(StatusType.ERROR, dse.getReasonType(), dse.getMessageToUser());
71 | }
72 |
73 | /**
74 | * Gets a modified response status in case of ReasonType#USER_NOT_AUTHENTICATED
75 | * by adding a sign in html link for the given url. If no url is provided in the
76 | * ResponseStatus# no change is made.
77 | *
78 | * @param responseStatus The response status.
79 | *
80 | * @return The modified response status if modified, or else the original response status.
81 | */
82 | public static ResponseStatus getModifiedResponseStatus(ResponseStatus responseStatus) {
83 |
84 | String signInString = LocaleUtil.getLocalizedMessageFromBundle(
85 | "com.google.visualization.datasource.base.ErrorMessages", SIGN_IN_MESSAGE_KEY, null);
86 | if (responseStatus.getReasonType() == ReasonType.USER_NOT_AUTHENTICATED) {
87 | String msg = responseStatus.getDescription();
88 | if (!msg.contains(" ")
89 | && (msg.startsWith("http://")
90 | || msg.startsWith("https://"))) {
91 | // The description is assumed to be a link to sign in page, transform the message into
92 | // an html snippet of a link.
93 | StringBuilder sb = new StringBuilder("")
95 | .append(signInString)
96 | .append("");
97 | responseStatus = new ResponseStatus(responseStatus.getStatusType(),
98 | responseStatus.getReasonType(), sb.toString());
99 | }
100 | }
101 | return responseStatus;
102 | }
103 |
104 | public ResponseStatus(StatusType statusType) {
105 | this(statusType, null, null);
106 | }
107 |
108 | /**
109 | * Returns the response status type.
110 | *
111 | * @return the response status type.
112 | */
113 | public StatusType getStatusType() {
114 | return statusType;
115 | }
116 |
117 | /**
118 | * Returns the response reason type.
119 | *
120 | * @return the response reason type.
121 | */
122 | public ReasonType getReasonType() {
123 | return reasonType;
124 | }
125 |
126 | /**
127 | * Returns the message to pass to the user.
128 | *
129 | * @return The message to pass to the user.
130 | */
131 | public String getDescription() {
132 | return description;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/examples/src/java/CsvDataSourceServlet.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import com.google.visualization.datasource.DataSourceHelper;
16 | import com.google.visualization.datasource.DataSourceServlet;
17 | import com.google.visualization.datasource.base.DataSourceException;
18 | import com.google.visualization.datasource.base.ReasonType;
19 | import com.google.visualization.datasource.datatable.DataTable;
20 | import com.google.visualization.datasource.query.Query;
21 | import com.google.visualization.datasource.util.CsvDataSourceHelper;
22 |
23 | import com.ibm.icu.util.ULocale;
24 |
25 | import org.apache.commons.lang.StringUtils;
26 | import org.apache.commons.logging.Log;
27 | import org.apache.commons.logging.LogFactory;
28 |
29 | import java.io.BufferedReader;
30 | import java.io.IOException;
31 | import java.io.InputStreamReader;
32 | import java.io.Reader;
33 | import java.net.MalformedURLException;
34 | import java.net.URL;
35 |
36 | import javax.servlet.http.HttpServletRequest;
37 |
38 | /**
39 | * A demo servlet for serving a simple, constant data table.
40 | * This servlet extends DataSourceServlet, but does not override the default
41 | * empty implementation of method getCapabilities(). This servlet therefore ignores the
42 | * user query (as passed in the 'tq' url parameter), leaving the
43 | * query engine to apply it to the data table created here.
44 | *
45 | * @author Nimrod T.
46 | */
47 | public class CsvDataSourceServlet extends DataSourceServlet {
48 |
49 | /**
50 | * Log.
51 | */
52 | private static final Log log = LogFactory.getLog(CsvDataSourceServlet.class.getName());
53 |
54 | /**
55 | * The name of the parameter that contains the url of the CSV to load.
56 | */
57 | private static final String URL_PARAM_NAME = "url";
58 |
59 | /**
60 | * Generates the data table.
61 | * This servlet assumes a special parameter that contains the CSV URL from which to load
62 | * the data.
63 | */
64 | @Override
65 | public DataTable generateDataTable(Query query, HttpServletRequest request)
66 | throws DataSourceException {
67 | String url = request.getParameter(URL_PARAM_NAME);
68 | if (StringUtils.isEmpty(url)) {
69 | log.error("url parameter not provided.");
70 | throw new DataSourceException(ReasonType.INVALID_REQUEST, "url parameter not provided");
71 | }
72 |
73 | Reader reader;
74 | try {
75 | reader = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
76 | } catch (MalformedURLException e) {
77 | log.error("url is malformed: " + url);
78 | throw new DataSourceException(ReasonType.INVALID_REQUEST, "url is malformed: " + url);
79 | } catch (IOException e) {
80 | log.error("Couldn't read from url: " + url, e);
81 | throw new DataSourceException(ReasonType.INVALID_REQUEST, "Couldn't read from url: " + url);
82 | }
83 | DataTable dataTable = null;
84 | ULocale requestLocale = DataSourceHelper.getLocaleFromRequest(request);
85 | try {
86 | // Note: We assume that all the columns in the CSV file are text columns. In cases where the
87 | // column types are known in advance, this behavior can be overridden by passing a list of
88 | // ColumnDescription objects specifying the column types. See CsvDataSourceHelper.read() for
89 | // more details.
90 | dataTable = CsvDataSourceHelper.read(reader, null, true, requestLocale);
91 | } catch (IOException e) {
92 | log.error("Couldn't read from url: " + url, e);
93 | throw new DataSourceException(ReasonType.INVALID_REQUEST, "Couldn't read from url: " + url);
94 | }
95 | return dataTable;
96 | }
97 |
98 | /**
99 | * NOTE: By default, this function returns true, which means that cross
100 | * domain requests are rejected.
101 | * This check is disabled here so examples can be used directly from the
102 | * address bar of the browser. Bear in mind that this exposes your
103 | * data source to xsrf attacks.
104 | * If the only use of the data source url is from your application,
105 | * that runs on the same domain, it is better to remain in restricted mode.
106 | */
107 | @Override
108 | protected boolean isRestrictedAccessMode() {
109 | return false;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/datatable/value/ValueType.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.datatable.value;
16 |
17 | import com.google.common.collect.Maps;
18 | import com.google.visualization.datasource.base.TypeMismatchException;
19 |
20 | import com.ibm.icu.util.GregorianCalendar;
21 |
22 | import java.util.Map;
23 |
24 | /**
25 | * Represents a supported value type for a table.
26 | *
27 | * @author Yoah B.D.
28 | */
29 | public enum ValueType {
30 | BOOLEAN("BOOLEAN"),
31 | NUMBER("NUMBER"),
32 | TEXT("STRING"),
33 | DATE("DATE"),
34 | TIMEOFDAY("TIMEOFDAY"),
35 | DATETIME("DATETIME");
36 |
37 | /**
38 | * The type code string for this ValueType.
39 | */
40 | private String typeCode;
41 |
42 | /**
43 | * Constructs a ValueType with a given type code string.
44 | *
45 | * @param typeCode The type code string for the ValueType.
46 | */
47 | ValueType(String typeCode) {
48 | this.typeCode = typeCode;
49 | }
50 |
51 | /**
52 | * Returns the type code string for this ValueType.
53 | *
54 | * @return The type code string for this ValueType.
55 | */
56 | String getTypeCode() {
57 | return typeCode;
58 | }
59 |
60 | /**
61 | * Returns the type code string for this ValueType as a lower case string.
62 | *
63 | * @return The type code string for this ValueType as a lower case string.
64 | */
65 | public String getTypeCodeLowerCase() {
66 | return typeCode.toLowerCase();
67 | }
68 |
69 | /**
70 | * Returns the correct ValueType for a given type code string.
71 | *
72 | * @param string The type code string.
73 | *
74 | * @return The correct ValueType for the type code string.
75 | */
76 | static ValueType getByTypeCode(String string) {
77 | return typeCodeToValueType.get(string);
78 | }
79 |
80 | /**
81 | * Holds the mapping of type code to an instance of this class.
82 | */
83 | private static Map typeCodeToValueType;
84 |
85 | /**
86 | * Creates a value of this ValueType. The value must be of an appropriate
87 | * class, otherwise an exception is thrown.
88 | * Java native types/classes are translated to Value in the following way:
89 | * String -> TextValue
90 | * Number (inc. all derivatives such as Integer, Double) -> NumberValue
91 | * Boolean -> BooleanValue
92 | * com.ibm.icu.util.GregorianCalendar -> DateValue, DateTimeValue or
93 | * TimeOfDayValue
94 | *
95 | * @param value The value to create.
96 | * @return A Value of this ValueType.
97 | * @throws TypeMismatchException When the type of value does not match this.
98 | */
99 | public Value createValue(Object value) throws TypeMismatchException {
100 | Value ret = null;
101 |
102 | if (value == null) {
103 | ret = Value.getNullValueFromValueType(this);
104 | } else if ((this == TEXT) &&
105 | ((value instanceof String) || value == null)) {
106 | ret = new TextValue((String) value);
107 | } else if ((this == NUMBER) && (value instanceof Number)) {
108 | ret = new NumberValue(((Number) value).doubleValue());
109 | } else if ((this == BOOLEAN) && (value instanceof Boolean)) {
110 | ret = ((Boolean) value).booleanValue() ? BooleanValue.TRUE
111 | : BooleanValue.FALSE;
112 | } else if ((this == DATE) && (value instanceof GregorianCalendar)) {
113 | ret = new DateValue((GregorianCalendar) value);
114 | } else if ((this == DATETIME) && (value instanceof GregorianCalendar)) {
115 | ret = new DateTimeValue((GregorianCalendar) value);
116 | } else if ((this == TIMEOFDAY) && (value instanceof GregorianCalendar)) {
117 | ret = new TimeOfDayValue((GregorianCalendar) value);
118 | }
119 |
120 | // If none of the above hold, we have a type mismatch.
121 | if (ret == null) {
122 | throw new TypeMismatchException("Value type mismatch.");
123 | }
124 |
125 | return ret;
126 | }
127 |
128 | /**
129 | * Initializes the static map.
130 | */
131 | static {
132 | typeCodeToValueType = Maps.newHashMap();
133 | for (ValueType type : ValueType.values()) {
134 | typeCodeToValueType.put(type.typeCode, type);
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/main/java/com/google/visualization/datasource/query/QueryGroup.java:
--------------------------------------------------------------------------------
1 | // Copyright 2009 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.visualization.datasource.query;
16 |
17 | import com.google.common.collect.ImmutableList;
18 | import com.google.common.collect.Lists;
19 |
20 | import java.util.List;
21 |
22 | /**
23 | * Grouping definition for a query.
24 | * Grouping is defined as a list of column IDs to group by.
25 | *
26 | * @author Yoav G.
27 | * @author Yonatan B.Y.
28 | * @author Liron L.
29 | */
30 | public class QueryGroup {
31 |
32 | /**
33 | * The list of group-by columns.
34 | */
35 | private List columns;
36 |
37 | /**
38 | * Constructs a query group with empty lists.
39 | */
40 | public QueryGroup() {
41 | columns = Lists.newArrayList();
42 | }
43 |
44 | /**
45 | * Add a column to group by.
46 | *
47 | * @param column The column to add.
48 | */
49 | public void addColumn(AbstractColumn column) {
50 | columns.add(column);
51 | }
52 |
53 | /**
54 | * Returns the list of group-by IDs. This list is immutable.
55 | *
56 | * @return The list of group-by IDs. This list is immutable.
57 | */
58 | public List getColumnIds() {
59 | List columnIds = Lists.newArrayList();
60 | for (AbstractColumn col : columns) {
61 | columnIds.add(col.getId());
62 | }
63 | return ImmutableList.copyOf(columnIds);
64 | }
65 |
66 | /**
67 | * Returns a list of all simple columns' IDs in this group.
68 | *
69 | * @return A list of all simple columns' IDs in this group.
70 | */
71 | public List getSimpleColumnIds() {
72 | List columnIds = Lists.newArrayList();
73 | for (AbstractColumn col : columns) {
74 | columnIds.addAll(col.getAllSimpleColumnIds());
75 | }
76 | return columnIds;
77 | }
78 |
79 | /**
80 | * Returns the list of group-by columns. This list is immutable.
81 | *
82 | * @return The list of group-by columns. This list is immutable.
83 | */
84 | public List getColumns() {
85 | return ImmutableList.copyOf(columns);
86 | }
87 |
88 | /**
89 | * Returns the list of simple columns included in the group-by section.
90 | *
91 | * @return The list of simple columns included in the group-by section.
92 | */
93 | public List getSimpleColumns() {
94 | List simpleColumns = Lists.newArrayList();
95 | for (AbstractColumn col : columns) {
96 | simpleColumns.addAll(col.getAllSimpleColumns());
97 | }
98 | return simpleColumns;
99 | }
100 |
101 | /**
102 | * Returns the list of scalar function columns included in the group-by
103 | * section.
104 | *
105 | * @return The list of scalar function columns included in the group-by
106 | * section
107 | */
108 | public List getScalarFunctionColumns() {
109 | List scalarFunctionColumns = Lists.newArrayList();
110 | for (AbstractColumn col : columns) {
111 | scalarFunctionColumns.addAll(col.getAllScalarFunctionColumns());
112 | }
113 | return scalarFunctionColumns;
114 | }
115 |
116 | @Override
117 | public int hashCode() {
118 | final int prime = 31;
119 | int result = 1;
120 | result = prime * result + ((columns == null) ? 0 : columns.hashCode());
121 | return result;
122 | }
123 |
124 | @Override
125 | public boolean equals(Object obj) {
126 | if (this == obj) {
127 | return true;
128 | }
129 | if (obj == null) {
130 | return false;
131 | }
132 | if (getClass() != obj.getClass()) {
133 | return false;
134 | }
135 | QueryGroup other = (QueryGroup) obj;
136 | if (columns == null) {
137 | if (other.columns != null) {
138 | return false;
139 | }
140 | } else if (!columns.equals(other.columns)) {
141 | return false;
142 | }
143 | return true;
144 | }
145 |
146 | /**
147 | * Returns a string that when fed to the query parser would produce an equal QueryGroup.
148 | * The string is returned without the GROUP BY keywords.
149 | *
150 | * @return The query string.
151 | */
152 | public String toQueryString() {
153 | return Query.columnListToQueryString(columns);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------