001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.modeshape.jdbc.delegate; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.LinkedHashMap; 023import java.util.List; 024import java.util.Map; 025import java.util.NoSuchElementException; 026import javax.jcr.Node; 027import javax.jcr.NodeIterator; 028import javax.jcr.Value; 029import javax.jcr.query.Row; 030import javax.jcr.query.RowIterator; 031import org.modeshape.jcr.api.query.QueryResult; 032import org.modeshape.jdbc.JdbcJcrValueFactory; 033 034/** 035 * A simple implementation of the {@link QueryResult} interface. 036 * 037 * @author Horia Chiorean 038 */ 039public final class HttpQueryResult implements QueryResult { 040 041 protected final List<HttpRow> rows = new ArrayList<>(); 042 protected final Map<String, String> columnTypesByName = new LinkedHashMap<>(); 043 044 protected HttpQueryResult( org.modeshape.jdbc.rest.QueryResult queryResult ) { 045 assert queryResult != null; 046 047 if (!queryResult.isEmpty()) { 048 this.columnTypesByName.putAll(queryResult.getColumns()); 049 050 for (org.modeshape.jdbc.rest.QueryResult.Row queryRow : queryResult) { 051 rows.add(new HttpRow(queryRow)); 052 } 053 } 054 } 055 056 @Override 057 public String getPlan() { 058 throw new UnsupportedOperationException("Method getPlan() not supported"); 059 } 060 061 @Override 062 public Collection<String> getWarnings() { 063 return Collections.emptyList(); 064 } 065 066 @Override 067 public String[] getColumnNames() { 068 return columnTypesByName.keySet().toArray(new String[columnTypesByName.size()]); 069 } 070 071 @Override 072 public boolean isEmpty() { 073 return rows.isEmpty(); 074 } 075 076 @Override 077 public RowIterator getRows() { 078 return new HttpRowIterator(); 079 } 080 081 @Override 082 public NodeIterator getNodes() { 083 throw new UnsupportedOperationException("Method getNodes() not supported"); 084 } 085 086 @Override 087 public String[] getSelectorNames() { 088 throw new UnsupportedOperationException("Method getSelectorNames() not supported"); 089 } 090 091 @Override 092 public void close() { 093 // do nothing 094 } 095 096 @Override 097 public String[] getColumnTypes() { 098 return columnTypesByName.values().toArray(new String[columnTypesByName.size()]); 099 } 100 101 private class HttpRowIterator implements RowIterator { 102 103 private static final int EMPTY_CURSOR = -1; 104 private int cursor = rows.isEmpty() ? EMPTY_CURSOR : 0; 105 106 protected HttpRowIterator() { 107 } 108 109 @Override 110 public Row nextRow() { 111 if (cursor == -1 || cursor >= rows.size()) { 112 throw new NoSuchElementException("No more rows to iterate over"); 113 } 114 return rows.get(cursor++); 115 } 116 117 @Override 118 public void skip( long skipNum ) { 119 if (skipNum < 0) { 120 throw new IllegalArgumentException("skipNum must be a positive value"); 121 } 122 int availableRowsCount = rows.size() - cursor; 123 if (skipNum > availableRowsCount) { 124 throw new NoSuchElementException("Skip would go past collection end"); 125 } 126 cursor += skipNum; 127 } 128 129 @Override 130 public long getSize() { 131 return rows.size(); 132 } 133 134 @Override 135 public long getPosition() { 136 return cursor; 137 } 138 139 @Override 140 public boolean hasNext() { 141 return cursor != -1 && cursor < rows.size(); 142 } 143 144 @Override 145 public Object next() { 146 return nextRow(); 147 } 148 149 @Override 150 public void remove() { 151 throw new UnsupportedOperationException("Method remove() not supported by this iterator"); 152 } 153 } 154 155 private class HttpRow implements Row { 156 private final Map<String, Value> valuesMap = new LinkedHashMap<>(); 157 158 protected HttpRow( org.modeshape.jdbc.rest.QueryResult.Row row ) { 159 assert row != null; 160 for (String columnName : columnTypesByName.keySet()) { 161 Object queryRowValue = row.getValue(columnName); 162 valuesMap.put(columnName, JdbcJcrValueFactory.createValue(queryRowValue)); 163 } 164 } 165 166 @Override 167 public Node getNode() { 168 throw new UnsupportedOperationException("Method getNode() not supported"); 169 } 170 171 @Override 172 public Value[] getValues() { 173 return valuesMap.values().toArray(new Value[valuesMap.size()]); 174 } 175 176 @Override 177 public Value getValue( String columnName ) { 178 return valuesMap.get(columnName); 179 } 180 181 @Override 182 public Node getNode( String selectorName ) { 183 throw new UnsupportedOperationException("Method getNode(selectorName) not supported"); 184 } 185 186 @Override 187 public String getPath() { 188 throw new UnsupportedOperationException("Method getPath() not supported"); 189 } 190 191 @Override 192 public String getPath( String selectorName ) { 193 throw new UnsupportedOperationException("Method getPath(selectorName) not supported"); 194 } 195 196 @Override 197 public double getScore() { 198 throw new UnsupportedOperationException("Method getScore() not supported"); 199 } 200 201 @Override 202 public double getScore( String selectorName ) { 203 throw new UnsupportedOperationException("Method getScore( String selectorName ) not supported"); 204 } 205 } 206}