Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* Copyright (c) 2026 MetaBrainz Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MusicBrainz project nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.musicbrainz.search.solrwriter.moxy;

import org.musicbrainz.mmd2.Relation;
import org.musicbrainz.mmd2.RelationList;
import org.musicbrainz.mmd2.DefAreaElementInner;

import java.util.ArrayList;
import java.util.List;

public class AreaAdapter extends NotUnmarshallableXmlAdapter<AreaAdapter.AdaptedArea, DefAreaElementInner> {

public static class AdaptedArea extends DefAreaElementInner {
public List<RelationAdapter.AdaptedRelation> relations;
}

/**
* Call when convert model to json, replaces area in model with adaptedArea
* which does not contain a list of RelationList, instead all relations in each existing
* RelationList are merged into a list of relations. We do this because it is not possible to merge
* a List of RelationLists into the area using oxml.xml mapping
*/
@Override
public AdaptedArea marshal(DefAreaElementInner area) throws Exception {
AdaptedArea adaptedArea = new AdaptedArea();
adaptedArea.relations = RelationListUtil.marshal(area.getRelationList());

//Also need to copy any other elements/attributes we may want to output
adaptedArea.setName(area.getName());
adaptedArea.setSortName(area.getSortName());
adaptedArea.setDisambiguation(area.getDisambiguation());
adaptedArea.setIso31661CodeList(area.getIso31661CodeList());
adaptedArea.setIso31662CodeList(area.getIso31662CodeList());
adaptedArea.setIso31663CodeList(area.getIso31663CodeList());
adaptedArea.setAnnotation(area.getAnnotation());
adaptedArea.setLifeSpan(area.getLifeSpan());
adaptedArea.setAliasList(area.getAliasList());
adaptedArea.setTagList(area.getTagList());
adaptedArea.setUserTagList(area.getUserTagList());
adaptedArea.setGenreList(area.getGenreList());
adaptedArea.setUserGenreList(area.getUserGenreList());
adaptedArea.setId(area.getId());
adaptedArea.setType(area.getType());
adaptedArea.setTypeId(area.getTypeId());
adaptedArea.setScore(area.getScore());

return adaptedArea;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,19 @@
public class EventAdapter extends NotUnmarshallableXmlAdapter<EventAdapter.AdaptedEvent, Event> {

public static class AdaptedEvent extends Event {
public List<Relation> relations = new ArrayList<Relation>();
public List<RelationAdapter.AdaptedRelation> relations;
}

/**
* Call when convert model to json, replaces work in model with adaptedWork
* Call when convert model to json, replaces event in model with adaptedEvent
* which does not contain a list of RelationList, instead all relations in each existing
* RelationList are merged into a list of relations. We do this because it is not possible to merge
* a List of RelationLists into the work using oxml.xml mapping
* a List of RelationLists into the event using oxml.xml mapping
*/
@Override
public AdaptedEvent marshal(Event event) throws Exception {
AdaptedEvent adaptedEvent = new AdaptedEvent();
for(RelationList relationList : event.getRelationList()) {
for(Relation relation : relationList.getRelation()) {
adaptedEvent.relations.add(relation);
}
}
adaptedEvent.relations = RelationListUtil.marshal(event.getRelationList());

//Also need to copy any other elements/attributes we may want to output
adaptedEvent.setAliasList(event.getAliasList());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* Copyright (c) 2026 MetaBrainz Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MusicBrainz project nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.musicbrainz.search.solrwriter.moxy;

import jakarta.xml.bind.annotation.XmlElement;
import org.musicbrainz.mmd2.Relation;

/**
* This adapter class only exists to extend `Relation` with a `target-type`
* attribute. Since the target type is only accessible on the parent
* `RelationList`, it's not actually assigned to here, but via
* `RelationListUtil.marshal`. All other relation properties are copied onto
* the adapted relation instance as-is.
*/

public class RelationAdapter extends NotUnmarshallableXmlAdapter<RelationAdapter.AdaptedRelation, Relation> {

public static class AdaptedRelation extends Relation {
@XmlElement(name = "target-type")
protected String targetType;
}

@Override
public AdaptedRelation marshal(Relation relation) throws Exception {
AdaptedRelation adaptedRelation = new AdaptedRelation();

adaptedRelation.setOrderingKey(relation.getOrderingKey());
adaptedRelation.setDirection(relation.getDirection());
adaptedRelation.setAttributeList(relation.getAttributeList());
adaptedRelation.setBegin(relation.getBegin());
adaptedRelation.setEnd(relation.getEnd());
adaptedRelation.setEnded(relation.getEnded());
adaptedRelation.setSourceCredit(relation.getSourceCredit());
adaptedRelation.setTargetCredit(relation.getTargetCredit());
adaptedRelation.setType(relation.getType());
adaptedRelation.setTypeId(relation.getTypeId());

adaptedRelation.setArea(relation.getArea());
adaptedRelation.setArtist(relation.getArtist());
adaptedRelation.setEvent(relation.getEvent());
adaptedRelation.setInstrument(relation.getInstrument());
adaptedRelation.setLabel(relation.getLabel());
adaptedRelation.setPlace(relation.getPlace());
adaptedRelation.setRecording(relation.getRecording());
adaptedRelation.setRelease(relation.getRelease());
adaptedRelation.setReleaseGroup(relation.getReleaseGroup());
adaptedRelation.setSeries(relation.getSeries());
adaptedRelation.setTarget(relation.getTarget());
adaptedRelation.setWork(relation.getWork());

return adaptedRelation;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2018 MetaBrainz Foundation
/* Copyright (c) 2026 MetaBrainz Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -28,12 +28,24 @@

package org.musicbrainz.search.solrwriter.moxy;

import org.musicbrainz.mmd2.Target;
import org.musicbrainz.mmd2.Relation;
import org.musicbrainz.mmd2.RelationList;
import java.util.ArrayList;
import java.util.List;

public class StringTargetAdapter extends NotUnmarshallableXmlAdapter<String, Target> {
@Override
public String marshal(Target v) throws Exception {
return v.getValue();
}
public class RelationListUtil {

public static List<RelationAdapter.AdaptedRelation> marshal(List<RelationList> relationLists) throws Exception {
List<RelationAdapter.AdaptedRelation> relations = new ArrayList<>();
RelationAdapter adapter = new RelationAdapter();
for (RelationList relationList : relationLists) {
String targetType = relationList.getTargetType();
for (Relation relation : relationList.getRelation()) {
RelationAdapter.AdaptedRelation adaptedRelation = adapter.marshal(relation);
adaptedRelation.targetType = targetType;
relations.add(adaptedRelation);
}
}
return relations;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* Copyright (c) 2026 MetaBrainz Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the MusicBrainz project nor the names of the
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.musicbrainz.search.solrwriter.moxy;

import org.musicbrainz.mmd2.Relation;
import org.musicbrainz.mmd2.RelationList;
import org.musicbrainz.mmd2.Url;

import java.util.ArrayList;
import java.util.List;

public class UrlAdapter extends NotUnmarshallableXmlAdapter<UrlAdapter.AdaptedUrl, Url> {

public static class AdaptedUrl extends Url {
public List<RelationAdapter.AdaptedRelation> relations;
}

/**
* Call when convert model to json, replaces url in model with adaptedUrl
* which does not contain a list of RelationList, instead all relations in each existing
* RelationList are merged into a list of relations. We do this because it is not possible to merge
* a List of RelationLists into the url using oxml.xml mapping
*/
@Override
public AdaptedUrl marshal(Url url) throws Exception {
AdaptedUrl adaptedUrl = new AdaptedUrl();
adaptedUrl.relations = RelationListUtil.marshal(url.getRelationList());

//Also need to copy any other elements/attributes we may want to output
adaptedUrl.setResource(url.getResource());
adaptedUrl.setId(url.getId());
adaptedUrl.setScore(url.getScore());

return adaptedUrl;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
public class WorkAdapter extends NotUnmarshallableXmlAdapter<WorkAdapter.AdaptedWork, Work> {

public static class AdaptedWork extends Work {
public List<Relation> relations = new ArrayList<Relation>();
public List<RelationAdapter.AdaptedRelation> relations;
public List<String> languages = new ArrayList<String>();
}

Expand All @@ -53,11 +53,7 @@ public static class AdaptedWork extends Work {
public AdaptedWork marshal(Work work) throws Exception {

AdaptedWork adaptedWork = new AdaptedWork();
for(RelationList relationList : work.getRelationList()) {
for(Relation relation : relationList.getRelation()) {
adaptedWork.relations.add(relation);
}
}
adaptedWork.relations = RelationListUtil.marshal(work.getRelationList());

LanguageList languageList = work.getLanguageList();
if (languageList != null)
Expand Down
15 changes: 9 additions & 6 deletions mb-solr/src/main/resources/oxml.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@
</java-type>
<java-type name="UrlList">
<java-attributes>
<xml-element java-attribute="url" name="urls"/>
<xml-element java-attribute="url" name="urls">
<xml-java-type-adapter value="org.musicbrainz.search.solrwriter.moxy.UrlAdapter"/>
</xml-element>
</java-attributes>
</java-type>
<java-type name="PuidList">
Expand All @@ -154,8 +156,10 @@
</java-attributes>
</java-type>
<java-type name="AreaList">
<java-attributes>
<xml-element java-attribute="area" name="areas"/>
<java-attributes>>
<xml-element java-attribute="area" name="areas">
<xml-java-type-adapter value="org.musicbrainz.search.solrwriter.moxy.AreaAdapter"/>
</xml-element>
</java-attributes>
</java-type>
<java-type name="PlaceList">
Expand Down Expand Up @@ -275,11 +279,10 @@
</java-attributes>
</java-type>
<java-type name="Relation">
<xml-java-type-adapter value="org.musicbrainz.search.solrwriter.moxy.RelationAdapter"/>
<java-attributes>
<xml-element java-attribute="attributeList" xml-path="."/>
<xml-element java-attribute="target">
<xml-java-type-adapter value="org.musicbrainz.search.solrwriter.moxy.StringTargetAdapter"/>
</xml-element>
<xml-transient java-attribute="target"/>
</java-attributes>
</java-type>
<java-type name="Relation$AttributeList">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.musicbrainz.search.solrwriter;

import java.util.ArrayList;
import java.util.Arrays;

public abstract class AbstractMBWriterEventTest extends AbstractMBWriterTest {
@Override
public ArrayList<String> getDoc() {
return new ArrayList<>(Arrays.asList(new String[]{
"event", "Wacken Open Air 2024",
"mbid", uuid}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.musicbrainz.search.solrwriter;

import java.util.ArrayList;
import java.util.Arrays;

public abstract class AbstractMBWriterUrlTest extends AbstractMBWriterTest {
@Override
public ArrayList<String> getDoc() {
return new ArrayList<>(Arrays.asList(new String[]{
"url", "https://www.nin.com/",
"mbid", uuid}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.musicbrainz.search.solrwriter;

import java.util.ArrayList;
import java.util.Arrays;

public abstract class AbstractMBWriterWorkTest extends AbstractMBWriterTest {
@Override
public ArrayList<String> getDoc() {
return new ArrayList<>(Arrays.asList(new String[]{
"work", "Poker Face",
"mbid", uuid}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.musicbrainz.search.solrwriter.json;

import org.musicbrainz.search.solrwriter.AbstractMBWriterEventTest;
import org.musicbrainz.search.solrwriter.MBJSONWriterTestInterface;

public class MBJSONWriterEventTest extends AbstractMBWriterEventTest implements MBJSONWriterTestInterface {
static {
corename = "event";
}
}
Loading