google-nomulus/java/google/registry/rde/RdeMarshaller.java
mcilwain aa2f283f7c Convert entire project to strict lexicographical import sort ordering
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127234970
2016-07-13 15:59:53 -04:00

161 lines
6.2 KiB
Java

// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
//
// 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 google.registry.rde;
import static com.google.common.base.Verify.verify;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.googlecode.objectify.Key;
import google.registry.model.ImmutableObject;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DomainResource;
import google.registry.model.host.HostResource;
import google.registry.model.rde.RdeMode;
import google.registry.model.registrar.Registrar;
import google.registry.tldconfig.idn.IdnTable;
import google.registry.util.FormattingLogger;
import google.registry.xjc.XjcXmlTransformer;
import google.registry.xjc.rde.XjcRdeContentsType;
import google.registry.xjc.rde.XjcRdeDeposit;
import google.registry.xjc.rde.XjcRdeDepositTypeType;
import google.registry.xjc.rde.XjcRdeMenuType;
import google.registry.xjc.rdeidn.XjcRdeIdn;
import google.registry.xjc.rdeidn.XjcRdeIdnElement;
import google.registry.xjc.rdepolicy.XjcRdePolicy;
import google.registry.xjc.rdepolicy.XjcRdePolicyElement;
import google.registry.xml.XmlException;
import google.registry.xml.XmlFragmentMarshaller;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.util.Collection;
import javax.annotation.concurrent.NotThreadSafe;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.MarshalException;
import org.joda.time.DateTime;
/** XML document <i>fragment</i> marshaller for RDE. */
@NotThreadSafe
public final class RdeMarshaller implements Serializable {
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
private static final long serialVersionUID = 202890386611768455L;
private transient XmlFragmentMarshaller memoizedMarshaller;
/** Returns top-portion of XML document. */
public String makeHeader(
String depositId, DateTime watermark, Collection<String> uris, int revision) {
// We can't make JAXB marshal half an element. So we're going to use a kludge where we provide
// it with the minimum data necessary to marshal a deposit, and then cut it up by manually.
XjcRdeMenuType menu = new XjcRdeMenuType();
menu.setVersion("1.0");
menu.getObjURIs().addAll(uris);
XjcRdePolicy policy = new XjcRdePolicy();
policy.setScope("this-will-be-trimmed");
policy.setElement("/make/strict/validation/pass");
XjcRdeContentsType contents = new XjcRdeContentsType();
contents.getContents().add(new XjcRdePolicyElement(policy));
XjcRdeDeposit deposit = new XjcRdeDeposit();
deposit.setId(depositId);
deposit.setWatermark(watermark);
deposit.setType(XjcRdeDepositTypeType.FULL);
if (revision > 0) {
deposit.setResend(revision);
}
deposit.setRdeMenu(menu);
deposit.setContents(contents);
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
XjcXmlTransformer.marshalStrict(deposit, os, UTF_8);
} catch (XmlException e) {
throw new RuntimeException(e);
}
String rdeDocument = os.toString();
String marker = "<rde:contents>\n";
int startOfContents = rdeDocument.indexOf(marker);
verify(startOfContents > 0, "Bad RDE document:\n%s", rdeDocument);
return rdeDocument.substring(0, startOfContents + marker.length());
}
/** Returns bottom-portion of XML document. */
public String makeFooter() {
return "\n</rde:contents>\n</rde:deposit>\n";
}
/** Turns XJC element into XML fragment, with schema validation. */
public String marshalStrictlyOrDie(JAXBElement<?> element) {
try {
return getMarshaller().marshal(element);
} catch (MarshalException e) {
throw new RuntimeException(e);
}
}
/** Turns {@link ContactResource} object into an XML fragment. */
public DepositFragment marshalContact(ContactResource contact) {
return marshalResource(RdeResourceType.CONTACT, contact,
ContactResourceToXjcConverter.convert(contact));
}
/** Turns {@link DomainResource} object into an XML fragment. */
public DepositFragment marshalDomain(DomainResource domain, RdeMode mode) {
return marshalResource(RdeResourceType.DOMAIN, domain,
DomainResourceToXjcConverter.convert(domain, mode));
}
/** Turns {@link HostResource} object into an XML fragment. */
public DepositFragment marshalHost(HostResource host) {
return marshalResource(RdeResourceType.HOST, host,
HostResourceToXjcConverter.convert(host));
}
/** Turns {@link Registrar} object into an XML fragment. */
public DepositFragment marshalRegistrar(Registrar registrar) {
return marshalResource(RdeResourceType.REGISTRAR, registrar,
RegistrarToXjcConverter.convert(registrar));
}
/** Turns {@link IdnTable} object into an XML fragment. */
public String marshalIdn(IdnTable idn) {
XjcRdeIdn bean = new XjcRdeIdn();
bean.setId(idn.getName());
bean.setUrl(idn.getUrl().toString());
bean.setUrlPolicy(idn.getPolicy().toString());
return marshalStrictlyOrDie(new XjcRdeIdnElement(bean));
}
private DepositFragment marshalResource(
RdeResourceType type, ImmutableObject resource, JAXBElement<?> element) {
String xml = "";
String error = "";
try {
xml = getMarshaller().marshal(element);
} catch (MarshalException e) {
error = String.format("RDE XML schema validation failed: %s\n%s%s\n",
Key.create(resource),
e.getLinkedException(),
getMarshaller().marshalLenient(element));
logger.severe(error);
}
return DepositFragment.create(type, xml, error);
}
private XmlFragmentMarshaller getMarshaller() {
return memoizedMarshaller != null
? memoizedMarshaller
: (memoizedMarshaller = XjcXmlTransformer.get().createFragmentMarshaller());
}
}