package net.jhorstmann.i18n.tools.xgettext; import java.io.File; import java.net.URLDecoder; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import net.jhorstmann.i18n.tools.MessageBundle; import net.jhorstmann.i18n.tools.ResourceUtils; import net.jhorstmann.i18n.tools.xml.NamespaceContextImpl; import net.jhorstmann.i18n.tools.xml.NestedContentHandler; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.fedorahosted.tennera.jgettext.Message; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; public class AbstractExtractorHandler extends NestedContentHandler implements Locator, NamespaceContext { private final NamespaceContextImpl namespaceContext; private final MessageBundle bundle; private Locator locator; private boolean relativizePaths; private boolean srcRefPaths; File rootDir; public AbstractExtractorHandler(XMLReader xmlreader, MessageBundle bundle) { this(xmlreader, bundle, null, false, true); } public AbstractExtractorHandler(XMLReader xmlreader, MessageBundle bundle, File rootDir, boolean relativizePaths, boolean srcRefPaths) { super(xmlreader); this.bundle = bundle; this.namespaceContext = new NamespaceContextImpl(); this.relativizePaths = relativizePaths; this.srcRefPaths = srcRefPaths; this.rootDir = rootDir; } private Message createMessage(String msgid) { Message msg = new Message(); if (srcRefPaths && locator != null) { String systemId = locator.getSystemId(); if (systemId != null) { if (relativizePaths && rootDir != null) { try { systemId = URLDecoder.decode(systemId, "UTF-8"); } catch (Exception e) { } Pattern ptnProtocol = Pattern.compile("([a-zA-Z]+://)"); Matcher m = ptnProtocol.matcher(systemId); String protocol = ""; if (m.find()) { // protocol = m.group(m.groupCount()); protocol = m.group(0); } int idx = StringUtils.isEmpty(protocol) ? -1 : systemId.lastIndexOf(protocol); String cleanRef = (idx != -1 ? systemId.substring(idx + protocol.length()) : systemId).replace(protocol, ""); /* * if (cleanRef.startsWith("/")) cleanRef = cleanRef.substring(1); */ // extract filename and filepath from cleanref final String fileName = FilenameUtils.getName(cleanRef); String filePath = FilenameUtils.getFullPath(cleanRef); if (filePath.startsWith("/") && filePath.contains(":")) // (absolute) DOS-Path with starting "/" ??? filePath = filePath.substring(1); systemId = ResourceUtils.getRelativePath(filePath + fileName, FilenameUtils.separatorsToUnix(rootDir.getAbsolutePath()), "/"); } int line = locator.getLineNumber(); if (line > 0) { msg.addSourceReference(systemId, line); } else { msg.addSourceReference(systemId); } } } msg.setMsgid(msgid); // msg.setFuzzy(true); return msg; } public Message addMessage(String msgid) { Message msg = createMessage(msgid); msg.setMsgstr(msgid); bundle.addMessage(msg); return msg; } public Message addMessage(String context, String message, String plural, String comment) { if (message == null) { throw new IllegalArgumentException("Message id must not be null"); } Message msg = createMessage(message); if (context != null && context.length() > 0) { msg.setMsgctxt(context); } if (plural != null && plural.length() > 0) { msg.setMsgidPlural(plural); msg.addMsgstrPlural("", 0); } if (comment != null && comment.length() > 0) { msg.addExtractedComment(comment); } bundle.addMessage(msg); return msg; } public Message addMessageWithContext(String msgctx, String msgid) { Message msg = createMessage(msgid); msg.setMsgctxt(msgctx); bundle.addMessage(msg); return msg; } public Message addMessageWithPlural(String msgidSingular, String msgidPlural) { Message msg = createMessage(msgidSingular); msg.setMsgidPlural(msgidPlural); bundle.addMessage(msg); return msg; } public Message addMessageWithContextAndPlural(String msgctx, String msgidSingular, String msgidPlural) { Message msg = createMessage(msgidSingular); msg.setMsgctxt(msgctx); msg.setMsgidPlural(msgidPlural); bundle.addMessage(msg); return msg; } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { namespaceContext.startPrefixMapping(prefix, uri); } @Override public void endPrefixMapping(String prefix) throws SAXException { namespaceContext.endPrefixMapping(prefix); } @Override public String getNamespaceURI(String prefix) { return namespaceContext.getNamespaceURI(prefix); } @Override public String getPrefix(String namespaceURI) { return namespaceContext.getPrefix(namespaceURI); } @Override public Iterator getPrefixes(String namespaceURI) { return namespaceContext.getPrefixes(namespaceURI); } public QName resolveQName(String name) { return namespaceContext.resolveQName(name); } @Override public int getLineNumber() { return locator != null ? locator.getLineNumber() : -1; } @Override public int getColumnNumber() { return locator != null ? locator.getColumnNumber() : -1; } @Override public String getSystemId() { return locator != null ? locator.getSystemId() : null; } @Override public String getPublicId() { return locator != null ? locator.getPublicId() : null; } @Override public void setDocumentLocator(Locator locator) { this.locator = locator; } }