-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
locations.geojson POC phase2: End-to-end partial support of json data #1810
Changes from 14 commits
f8a966d
204f931
e7751f0
1131d7d
f027e9a
2eae957
ae500ef
acab716
138d550
e1ea3f1
435876e
75e8d80
1e9fac5
209d203
b82b39b
8bdab6d
6f82f03
77805f3
e3dbb2b
63d03e9
bffef74
c90bd7e
b794c3a
4badc74
2380dae
67504ab
3e6845c
2a423cc
86ea2c3
63b7d62
361d444
1ac48f5
92a9952
ee77597
beac89b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.mobilitydata.gtfsvalidator.notice; | ||
|
||
import static org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice.SectionRef.FILE_REQUIREMENTS; | ||
import static org.mobilitydata.gtfsvalidator.notice.SeverityLevel.ERROR; | ||
|
||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice; | ||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice.SectionRefs; | ||
import org.mobilitydata.gtfsvalidator.annotation.GtfsValidationNotice.UrlRef; | ||
|
||
/** | ||
* Feature id from locations.geojson already used. | ||
* | ||
* <p>The id of one of the features of the locations.geojson file already exists in stops.txt or | ||
* location_groups.txt | ||
*/ | ||
@GtfsValidationNotice( | ||
severity = ERROR, | ||
sections = @SectionRefs(FILE_REQUIREMENTS), | ||
urls = { | ||
@UrlRef( | ||
label = "Original Python validator implementation", | ||
url = "https://github.com/google/transitfeed") | ||
}) | ||
public class UniqueLocationIdViolationNotice extends ValidationNotice { | ||
|
||
/** The id that already exists. */ | ||
private final String id; | ||
|
||
/** The name of the file that already has this id. */ | ||
private final String fileWithIdAlreadyPresent; | ||
|
||
/** The name of the field that contains this id. */ | ||
private final String fieldNameInFile; | ||
|
||
/** The row of the record in the file where the id is already present. */ | ||
private final int csvRowNumber; | ||
|
||
public UniqueLocationIdViolationNotice( | ||
String id, String fileWithIdAlreadyPresent, String fieldNameInFile, int csvRowNumber) { | ||
|
||
this.id = id; | ||
this.fileWithIdAlreadyPresent = fileWithIdAlreadyPresent; | ||
this.fieldNameInFile = fieldNameInFile; | ||
this.csvRowNumber = csvRowNumber; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.mobilitydata.gtfsvalidator.table; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public abstract class GtfsContainer<T extends GtfsEntity, D extends GtfsDescriptor> { | ||
|
||
private final D descriptor; | ||
private final TableStatus tableStatus; | ||
|
||
public GtfsContainer(D descriptor, TableStatus tableStatus) { | ||
this.tableStatus = tableStatus; | ||
this.descriptor = descriptor; | ||
} | ||
|
||
public TableStatus getTableStatus() { | ||
return tableStatus; | ||
} | ||
|
||
public D getDescriptor() { | ||
return descriptor; | ||
} | ||
|
||
public abstract Class<T> getEntityClass(); | ||
|
||
public int entityCount() { | ||
return getEntities().size(); | ||
} | ||
|
||
public abstract List<T> getEntities(); | ||
|
||
public abstract String gtfsFilename(); | ||
|
||
public abstract Optional<T> byTranslationKey(String recordId, String recordSubId); | ||
|
||
public boolean isMissingFile() { | ||
return tableStatus == TableStatus.MISSING_FILE; | ||
} | ||
|
||
public boolean isParsedSuccessfully() { | ||
switch (tableStatus) { | ||
case PARSABLE_HEADERS_AND_ROWS: | ||
return true; | ||
case MISSING_FILE: | ||
return !descriptor.isRequired(); | ||
default: | ||
return false; | ||
} | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, class comment could be useful. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added class comments. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.mobilitydata.gtfsvalidator.table; | ||
|
||
// TODO: review class name maybe GtfsFileDescriptor | ||
public abstract class GtfsDescriptor<T extends GtfsEntity> { | ||
|
||
public abstract <C extends GtfsContainer> C createContainerForInvalidStatus( | ||
TableStatus tableStatus); | ||
|
||
// True if the specified file is required in a feed. | ||
private boolean required; | ||
|
||
private TableStatus tableStatus; | ||
|
||
public abstract boolean isRecommended(); | ||
|
||
public abstract Class<T> getEntityClass(); | ||
|
||
public abstract String gtfsFilename(); | ||
|
||
public boolean isRequired() { | ||
return this.required; | ||
} | ||
|
||
public void setRequired(boolean required) { | ||
this.required = required; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,20 +18,19 @@ | |||||
|
||||||
import com.google.common.base.Ascii; | ||||||
import java.util.*; | ||||||
import org.mobilitydata.gtfsvalidator.table.GtfsTableContainer.TableStatus; | ||||||
|
||||||
/** | ||||||
* Container for a whole parsed GTFS feed with all its tables. | ||||||
* | ||||||
* <p>The tables are kept as {@code GtfsTableContainer} instances. | ||||||
* <p>The tables are kept as {@code GtfsContainer} instances. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [doc]:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
*/ | ||||||
public class GtfsFeedContainer { | ||||||
private final Map<String, GtfsTableContainer<?>> tables = new HashMap<>(); | ||||||
private final Map<Class<? extends GtfsTableContainer>, GtfsTableContainer<?>> tablesByClass = | ||||||
private final Map<String, GtfsContainer<?, ?>> tables = new HashMap<>(); | ||||||
private final Map<Class<? extends GtfsContainer>, GtfsContainer<?, ?>> tablesByClass = | ||||||
new HashMap<>(); | ||||||
|
||||||
public GtfsFeedContainer(List<GtfsTableContainer<?>> tableContainerList) { | ||||||
for (GtfsTableContainer<?> table : tableContainerList) { | ||||||
public GtfsFeedContainer(List<GtfsContainer<?, ?>> tableContainerList) { | ||||||
for (GtfsContainer<?, ?> table : tableContainerList) { | ||||||
tables.put(table.gtfsFilename(), table); | ||||||
tablesByClass.put(table.getClass(), table); | ||||||
} | ||||||
|
@@ -49,11 +48,12 @@ public GtfsFeedContainer(List<GtfsTableContainer<?>> tableContainerList) { | |||||
* @param filename file name, including ".txt" extension | ||||||
* @return GTFS table or empty if the table is not supported by schema | ||||||
*/ | ||||||
public Optional<GtfsTableContainer<?>> getTableForFilename(String filename) { | ||||||
return Optional.ofNullable(tables.getOrDefault(Ascii.toLowerCase(filename), null)); | ||||||
public <T extends GtfsContainer<?, ?>> Optional<T> getTableForFilename(String filename) { | ||||||
return (Optional<T>) | ||||||
Optional.ofNullable(tables.getOrDefault(Ascii.toLowerCase(filename), null)); | ||||||
} | ||||||
|
||||||
public <T extends GtfsTableContainer<?>> T getTable(Class<T> clazz) { | ||||||
public <T extends GtfsContainer<?, ?>> T getTable(Class<T> clazz) { | ||||||
return (T) tablesByClass.get(clazz); | ||||||
} | ||||||
|
||||||
|
@@ -65,21 +65,21 @@ public <T extends GtfsTableContainer<?>> T getTable(Class<T> clazz) { | |||||
* @return true if all files were successfully parsed, false otherwise | ||||||
*/ | ||||||
public boolean isParsedSuccessfully() { | ||||||
for (GtfsTableContainer<?> table : tables.values()) { | ||||||
for (GtfsContainer<?, ?> table : tables.values()) { | ||||||
if (!table.isParsedSuccessfully()) { | ||||||
return false; | ||||||
} | ||||||
} | ||||||
return true; | ||||||
} | ||||||
|
||||||
public Collection<GtfsTableContainer<?>> getTables() { | ||||||
public Collection<GtfsContainer<?, ?>> getTables() { | ||||||
return tables.values(); | ||||||
} | ||||||
|
||||||
public String tableTotalsText() { | ||||||
List<String> totalList = new ArrayList<>(); | ||||||
for (GtfsTableContainer<?> table : tables.values()) { | ||||||
for (GtfsContainer<?, ?> table : tables.values()) { | ||||||
if (table.getTableStatus() == TableStatus.MISSING_FILE | ||||||
&& !table.getDescriptor().isRequired()) { | ||||||
continue; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add class comments to help understanding the purpose of this abstract class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added class comments.