/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.model.internal.reference; import java.util.List; import java.util.Locale; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import org.xwiki.component.annotation.Component; import org.xwiki.model.EntityType; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.EntityReference; import org.xwiki.model.reference.EntityReferenceSerializer; /** * <p> * Serialize a reference into a unique identifier string within a wiki. Its similar to the * {@link UidStringEntityReferenceSerializer}, but is made appropriate for a wiki independent storage. * </p> * <p> * The string created looks like {@code 5:space3:doc} for the {@code wiki:space.doc} document reference. and * {@code 5:space3:doc15:xspace.class[0]} for the wiki:space.doc^wiki:xspace.class[0] object. (with {@code 5} being the * length of the space name, i.e the length of {@code space} and {@code 3} being the length of the page name, i.e. the * length of {@code doc}). * </p> * * @version $Id: 2db3e238086a32b8dc6bf43a2e1b3869df59b093 $ * @since 4.0M1 * @see UidStringEntityReferenceSerializer */ @Component @Named("local/uid") @Singleton public class LocalUidStringEntityReferenceSerializer implements EntityReferenceSerializer<String> { /** * Unique instance of the uid serializer. */ public static final LocalUidStringEntityReferenceSerializer INSTANCE = new LocalUidStringEntityReferenceSerializer(); @Inject private SymbolScheme symbolScheme; @Override public String serialize(EntityReference reference, Object... parameters) { if (reference == null) { return null; } StringBuilder representation = new StringBuilder(); List<EntityReference> references = reference.getReversedReferenceChain(); EntityReference wikiReference = references.get(0); int index; if (wikiReference.getType() == EntityType.WIKI) { index = 1; } else { index = 0; } for (; index < reference.size(); ++index) { serializeEntityReference(references.get(index), representation, wikiReference, parameters); } return representation.toString(); } /** * Serialize a single reference element into the representation string builder. * * @param currentReference the reference to serialize * @param representation the builder where to happen the serialized member * @param wikiReference the wiki reference of this entity reference * @param parameters optional parameters */ protected void serializeEntityReference(EntityReference currentReference, StringBuilder representation, EntityReference wikiReference, Object... parameters) { String name = currentReference.getName(); // FIXME: Not really nice to parse here the serialized XClass reference to remove its wiki name when local. // This also why this is not a simple derived class of UidStringEntityReferenceSerializer. if (wikiReference != null && currentReference.getType() == EntityType.OBJECT) { if (name.startsWith(wikiReference.getName() + this.symbolScheme.getSeparatorSymbols().get(EntityType.SPACE).get(EntityType.WIKI))) { name = name.substring(wikiReference.getName().length() + 1); } } representation.append(name.length()).append(':').append(name); // Append Locale if (currentReference instanceof DocumentReference) { Locale locale = ((DocumentReference) currentReference).getLocale(); if (locale != null) { String localeString = locale.toString(); if (!localeString.isEmpty()) { representation.append(localeString.length()).append(':').append(localeString); } } } } }