METAMODEL-1165: Fixed - added default_table alias table
[metamodel.git] / json / src / main / java / org / apache / metamodel / json / JsonDataContext.java
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.metamodel.json;
20
21 import java.io.File;
22 import java.io.InputStream;
23 import java.util.List;
24 import java.util.stream.Collectors;
25
26 import org.apache.metamodel.DataContext;
27 import org.apache.metamodel.MetaModelException;
28 import org.apache.metamodel.QueryPostprocessDataContext;
29 import org.apache.metamodel.convert.DocumentConverter;
30 import org.apache.metamodel.data.CachingDataSetHeader;
31 import org.apache.metamodel.data.DataSet;
32 import org.apache.metamodel.data.DataSetHeader;
33 import org.apache.metamodel.data.DocumentSource;
34 import org.apache.metamodel.data.DocumentSourceDataSet;
35 import org.apache.metamodel.data.MaxRowsDataSet;
36 import org.apache.metamodel.data.MaxRowsDocumentSource;
37 import org.apache.metamodel.query.SelectItem;
38 import org.apache.metamodel.schema.Column;
39 import org.apache.metamodel.schema.Schema;
40 import org.apache.metamodel.schema.Table;
41 import org.apache.metamodel.schema.builder.DocumentSourceProvider;
42 import org.apache.metamodel.schema.builder.SchemaBuilder;
43 import org.apache.metamodel.schema.builder.SingleTableInferentialSchemaBuilder;
44 import org.apache.metamodel.util.FileHelper;
45 import org.apache.metamodel.util.FileResource;
46 import org.apache.metamodel.util.Resource;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import com.fasterxml.jackson.core.JsonParser;
51 import com.fasterxml.jackson.databind.MappingJsonFactory;
52
53 /**
54 * {@link DataContext} implementation that works on JSON files or
55 * {@link Resource}s.
56 */
57 public class JsonDataContext extends QueryPostprocessDataContext implements DocumentSourceProvider {
58
59 private static final Logger logger = LoggerFactory.getLogger(JsonDataContext.class);
60
61 private final Resource _resource;
62 private final SchemaBuilder _schemaBuilder;
63
64 public JsonDataContext(File file) {
65 this(new FileResource(file));
66 }
67
68 public JsonDataContext(Resource resource) {
69 this(resource, new SingleTableInferentialSchemaBuilder(resource));
70 }
71
72 public JsonDataContext(Resource resource, SchemaBuilder schemaBuilder) {
73 super(false);
74 _resource = resource;
75 _schemaBuilder = schemaBuilder;
76 }
77
78 @Override
79 protected Schema getMainSchema() throws MetaModelException {
80 _schemaBuilder.offerSources(this);
81 return _schemaBuilder.build();
82 }
83
84 @Override
85 protected String getMainSchemaName() throws MetaModelException {
86 return _schemaBuilder.getSchemaName();
87 }
88
89 @Override
90 protected DataSet materializeMainSchemaTable(Table table, List<Column> columns, int maxRows) {
91 final DocumentConverter documentConverter = _schemaBuilder.getDocumentConverter(table);
92 final List<SelectItem> selectItems = columns.stream().map(SelectItem::new).collect(Collectors.toList());
93 final DataSetHeader header = new CachingDataSetHeader(selectItems);
94 final DocumentSource documentSource = getDocumentSourceForTable(table.getName());
95
96 DataSet dataSet = new DocumentSourceDataSet(header, documentSource, documentConverter);
97
98 if (maxRows > 0) {
99 dataSet = new MaxRowsDataSet(dataSet, maxRows);
100 }
101
102 return dataSet;
103 }
104
105 private DocumentSource createDocumentSource() {
106 final InputStream inputStream = _resource.read();
107 try {
108 final MappingJsonFactory jsonFactory = new MappingJsonFactory();
109 final JsonParser parser = jsonFactory.createParser(inputStream);
110 logger.debug("Created JSON parser for resource: {}", _resource);
111
112 return new JsonDocumentSource(parser, _resource.getName());
113 } catch (Exception e) {
114 FileHelper.safeClose(inputStream);
115 throw new MetaModelException("Unexpected error while creating JSON parser", e);
116 }
117 }
118
119 @Override
120 public DocumentSource getMixedDocumentSourceForSampling() {
121 return new MaxRowsDocumentSource(createDocumentSource(), 1000);
122 }
123
124 @Override
125 public DocumentSource getDocumentSourceForTable(String sourceCollectionName) {
126 // only a single source collection - returning that
127 return createDocumentSource();
128 }
129 }