Skip to content
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

Branding #536

Merged
merged 16 commits into from
Feb 4, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.concurrent.atomic.AtomicLong;
import no.entur.uttu.export.model.AvailabilityPeriod;
import no.entur.uttu.export.model.ServiceLinkExportContext;
import no.entur.uttu.model.Branding;
import no.entur.uttu.model.DayType;
import no.entur.uttu.model.DestinationDisplay;
import no.entur.uttu.model.FlexibleStopPlace;
Expand Down Expand Up @@ -62,6 +63,8 @@ public class NetexExportContext {

public Set<ServiceLinkExportContext> serviceLinks = new HashSet();

public Set<Branding> brandings = new HashSet<>();

private Map<String, AtomicLong> idSequences = new HashMap<>();

private Export export;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ public <F extends Common_VersionFrameStructure> CompositeFrame createCompositeFr
public ResourceFrame createResourceFrame(
NetexExportContext context,
Collection<Authority> authorities,
Collection<Operator> operators
Collection<Operator> operators,
Collection<Branding> brandings
) {
String resourceFrameId = NetexIdProducer.generateId(ResourceFrame.class, context);
OrganisationsInFrame_RelStructure organisationsStruct = objectFactory
Expand All @@ -229,11 +230,28 @@ public ResourceFrame createResourceFrame(
.collect(Collectors.toList())
);

return objectFactory
var resourceFrame = objectFactory
.createResourceFrame()
.withOrganisations(organisationsStruct)
.withVersion(VERSION_ONE)
.withId(resourceFrameId);

if (!brandings.isEmpty()) {
TypesOfValueInFrame_RelStructure typesOfValueStruct = objectFactory
.createTypesOfValueInFrame_RelStructure()
.withValueSetOrTypeOfValue(
brandings
.stream()
.map(Branding_VersionStructure.class::cast)
.distinct()
.map(this::wrapAsJAXBElement)
.collect(Collectors.toList())
);

resourceFrame = resourceFrame.withTypesOfValue(typesOfValueStruct);
}

return resourceFrame;
}

private static Collector<Organisation_VersionStructure, ?, Map<String, Organisation_VersionStructure>> toDistinctOrganisation() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package no.entur.uttu.export.netex.producer.common;

import java.util.List;
import java.util.stream.Collectors;
import no.entur.uttu.export.netex.NetexExportContext;
import org.rutebanken.netex.model.Branding;
import org.rutebanken.netex.model.MultilingualString;
import org.springframework.stereotype.Component;

@Component
public class BrandingProducer {

public List<Branding> produce(NetexExportContext context) {
return context.brandings
.stream()
.map(branding ->
new Branding()
.withId(branding.getNetexId())
.withVersion("1")
.withName(new MultilingualString().withValue(branding.getName()))
.withShortName(
branding.getShortName() != null
? new MultilingualString().withValue(branding.getShortName())
: null
)
.withDescription(
branding.getDescription() != null
? new MultilingualString().withValue(branding.getDescription())
: null
)
.withUrl(branding.getUrl())
.withImage(branding.getImageUrl())
)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import no.entur.uttu.model.Ref;
import no.entur.uttu.util.ExportUtil;
import org.rutebanken.netex.model.Authority;
import org.rutebanken.netex.model.Branding;
import org.rutebanken.netex.model.CompositeFrame;
import org.rutebanken.netex.model.DestinationDisplay;
import org.rutebanken.netex.model.FlexibleStopAssignment;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class NetexCommonFileProducer {
private final ServiceCalendarFrameProducer serviceCalendarFrameProducer;
private final NetworkProducer networkProducer;
private final ServiceLinkProducer serviceLinkProducer;
private final BrandingProducer brandingProducer;

@Value("${export.blob.commonFileFilenameSuffix:_flexible_shared_data}")
private String commonFileFilenameSuffix;
Expand All @@ -72,14 +74,16 @@ public NetexCommonFileProducer(
FlexibleStopPlaceProducer flexibleStopPlaceProducer,
ServiceCalendarFrameProducer serviceCalendarFrameProducer,
NetworkProducer networkProducer,
ServiceLinkProducer serviceLinkProducer
ServiceLinkProducer serviceLinkProducer,
BrandingProducer brandingProducer
) {
this.objectFactory = objectFactory;
this.organisationProducer = organisationProducer;
this.flexibleStopPlaceProducer = flexibleStopPlaceProducer;
this.serviceCalendarFrameProducer = serviceCalendarFrameProducer;
this.networkProducer = networkProducer;
this.serviceLinkProducer = serviceLinkProducer;
this.brandingProducer = brandingProducer;
}

public NetexFile toCommonFile(NetexExportContext context) {
Expand Down Expand Up @@ -112,7 +116,13 @@ public NetexFile toCommonFile(NetexExportContext context) {
private ResourceFrame createResourceFrame(NetexExportContext context) {
List<Operator> netexOperators = organisationProducer.produceOperators(context);
List<Authority> netexAuthorities = organisationProducer.produceAuthorities(context);
return objectFactory.createResourceFrame(context, netexAuthorities, netexOperators);
List<Branding> brandings = brandingProducer.produce(context);
return objectFactory.createResourceFrame(
context,
netexAuthorities,
netexOperators,
brandings
);
}

private SiteFrame createSiteFrame(NetexExportContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.rutebanken.netex.model.AllVehicleModesOfTransportEnumeration;
import org.rutebanken.netex.model.BookingAccessEnumeration;
import org.rutebanken.netex.model.BookingMethodEnumeration;
import org.rutebanken.netex.model.BrandingRefStructure;
import org.rutebanken.netex.model.FlexibleLineTypeEnumeration;
import org.rutebanken.netex.model.Line_VersionStructure;
import org.rutebanken.netex.model.NoticeAssignment;
Expand Down Expand Up @@ -96,6 +97,13 @@ protected void mapCommon(
);
context.networks.add(local.getNetwork());
context.notices.addAll(local.getNotices());

if (local.getBranding() != null) {
netex.setBrandingRef(
new BrandingRefStructure().withRef(local.getBranding().getNetexId())
);
context.brandings.add(local.getBranding());
}
}

protected void mapBookingArrangements(
Expand Down
67 changes: 67 additions & 0 deletions src/main/java/no/entur/uttu/graphql/LinesGraphQLSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static graphql.schema.GraphQLObjectType.newObject;
import static no.entur.uttu.graphql.GraphQLNames.*;

import graphql.GraphQL;
import graphql.Scalars;
import graphql.schema.DataFetcher;
import graphql.schema.GraphQLArgument;
Expand Down Expand Up @@ -60,6 +61,7 @@
import no.entur.uttu.graphql.scalars.LocalTimeScalar;
import no.entur.uttu.model.BookingAccessEnumeration;
import no.entur.uttu.model.BookingMethodEnumeration;
import no.entur.uttu.model.Branding;
import no.entur.uttu.model.DayType;
import no.entur.uttu.model.DayTypeAssignment;
import no.entur.uttu.model.DirectionTypeEnumeration;
Expand All @@ -79,6 +81,7 @@
import no.entur.uttu.model.job.ExportStatusEnumeration;
import no.entur.uttu.model.job.SeverityEnumeration;
import no.entur.uttu.profile.Profile;
import no.entur.uttu.repository.BrandingRepository;
import no.entur.uttu.repository.DataSpaceCleaner;
import no.entur.uttu.repository.DayTypeRepository;
import no.entur.uttu.repository.ExportRepository;
Expand All @@ -99,6 +102,9 @@
@Component
public class LinesGraphQLSchema {

public static final String FIELD_BRANDING_REF = "brandingRef";
public static final String FIELD_BRANDING = "branding";

@Autowired
private DateTimeScalar dateTimeScalar;

Expand Down Expand Up @@ -165,6 +171,12 @@ public class LinesGraphQLSchema {
@Autowired
private DataFetcher<ServiceLink> routingFetcher;

@Autowired
private BrandingRepository brandingRepository;

@Autowired
private DataFetcher<Branding> brandingUpdater;

private <T extends Enum> GraphQLEnumType createEnum(
String name,
T[] values,
Expand Down Expand Up @@ -269,6 +281,7 @@ private <T extends Enum> GraphQLEnumType createEnum(
private GraphQLObjectType organisationObjectType;
private GraphQLObjectType routeGeometryObjectType;
private GraphQLObjectType serviceLinkObjectType;
private GraphQLObjectType brandingObjectType;

private GraphQLArgument idArgument;
private GraphQLArgument idsArgument;
Expand Down Expand Up @@ -690,6 +703,16 @@ private void initCommonTypes() {
)
.build();

brandingObjectType =
newObject(identifiedEntityObjectType)
.name("Branding")
.field(newFieldDefinition().name("name").type(new GraphQLNonNull(GraphQLString)))
.field(newFieldDefinition().name("shortName").type(GraphQLString))
.field(newFieldDefinition().name("description").type(GraphQLString))
.field(newFieldDefinition().name("url").type(GraphQLString))
.field(newFieldDefinition().name("imageUrl").type(GraphQLString))
.build();

lineObjectType =
newObject(groupOfEntitiesObjectType)
.name("Line")
Expand All @@ -713,6 +736,7 @@ private void initCommonTypes() {
.name(FIELD_NETWORK)
.type(new GraphQLNonNull(networkObjectType))
)
.field(newFieldDefinition().name(FIELD_BRANDING).type(brandingObjectType))
.field(newFieldDefinition().name(FIELD_OPERATOR_REF).type(GraphQLString))
.field(
newFieldDefinition()
Expand Down Expand Up @@ -1072,6 +1096,21 @@ private GraphQLObjectType createQueryObject() {
.argument(idArgument)
.dataFetcher(env -> networkRepository.getOne(env.getArgument(FIELD_ID)))
)
.field(
newFieldDefinition()
.type(new GraphQLList(brandingObjectType))
.name("brandings")
.description("List of brandings")
.dataFetcher(env -> brandingRepository.findAll())
)
.field(
newFieldDefinition()
.type(brandingObjectType)
.name(FIELD_BRANDING)
.description("Get branding by id")
.argument(idArgument)
.dataFetcher(env -> brandingRepository.getOne(env.getArgument(FIELD_ID)))
)
.field(
newFieldDefinition()
.type(new GraphQLList(exportObjectType))
Expand Down Expand Up @@ -1209,6 +1248,15 @@ private GraphQLObjectType createMutationObject() {
)
.build();

GraphQLInputObjectType brandingInputType = newInputObject(identifiedEntityInputType)
.name("BrandingInput")
.field(newInputObjectField().name("name").type(new GraphQLNonNull(GraphQLString)))
.field(newInputObjectField().name("shortName").type(GraphQLString))
.field(newInputObjectField().name("description").type(GraphQLString))
.field(newInputObjectField().name("url").type(GraphQLString))
.field(newInputObjectField().name("imageUrl").type(GraphQLString))
.build();

GraphQLInputObjectType keyValuesInputType = newInputObject()
.name("KeyValuesInput")
.field(newInputObjectField().name(FIELD_KEY).type(GraphQLString))
Expand Down Expand Up @@ -1494,6 +1542,7 @@ private GraphQLObjectType createMutationObject() {
.name(FIELD_NETWORK_REF)
.type(new GraphQLNonNull(GraphQLString))
)
.field(newInputObjectField().name(FIELD_BRANDING_REF).type(GraphQLString))
.field(newInputObjectField().name(FIELD_OPERATOR_REF).type(GraphQLString))
.field(
newInputObjectField()
Expand Down Expand Up @@ -1567,6 +1616,24 @@ private GraphQLObjectType createMutationObject() {
.argument(idArgument)
.dataFetcher(networkUpdater)
)
.field(
newFieldDefinition()
.type(new GraphQLNonNull(brandingObjectType))
.name("mutateBranding")
.description("Create new or update existing branding")
.argument(
GraphQLArgument.newArgument().name(FIELD_INPUT).type(brandingInputType)
)
.dataFetcher(brandingUpdater)
)
.field(
newFieldDefinition()
.type(new GraphQLNonNull(brandingObjectType))
.name("deleteBranding")
.description("Delete an existing branding")
.argument(idArgument)
.dataFetcher(brandingUpdater)
)
.field(
newFieldDefinition()
.type(new GraphQLNonNull(lineObjectType))
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/no/entur/uttu/graphql/fetchers/BrandingUpdater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package no.entur.uttu.graphql.fetchers;

import graphql.schema.DataFetchingEnvironment;
import no.entur.uttu.error.codederror.EntityHasReferencesCodedError;
import no.entur.uttu.graphql.mappers.AbstractProviderEntityMapper;
import no.entur.uttu.model.Branding;
import no.entur.uttu.repository.FixedLineRepository;
import no.entur.uttu.repository.FlexibleLineRepository;
import no.entur.uttu.repository.generic.ProviderEntityRepository;
import no.entur.uttu.util.Preconditions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("brandingUpdater")
@Transactional
public class BrandingUpdater extends AbstractProviderEntityUpdater<Branding> {

private final FixedLineRepository fixedLineRepository;
private final FlexibleLineRepository flexibleLineRepository;

public BrandingUpdater(
AbstractProviderEntityMapper<Branding> mapper,
ProviderEntityRepository<Branding> repository,
FixedLineRepository fixedLineRepository,
FlexibleLineRepository flexibleLineRepository
) {
super(mapper, repository);
this.fixedLineRepository = fixedLineRepository;
this.flexibleLineRepository = flexibleLineRepository;
}

@Override
protected Branding deleteEntity(DataFetchingEnvironment env) {
return super.deleteEntity(env);
}

@Override
protected void verifyDeleteAllowed(String id) {
var branding = repository.getOne(id);
if (branding != null) {
long noOfLines =
fixedLineRepository.countByBranding(branding) +
flexibleLineRepository.countByBranding(branding);
Preconditions.checkArgument(
noOfLines == 0,
EntityHasReferencesCodedError.fromNumberOfReferences((int) noOfLines),
"%s cannot be deleted as it is referenced by %s line(s)",
branding.identity(),
noOfLines
);
}
super.verifyDeleteAllowed(id);
}
}
Loading