Java tutorial
/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.hibernate.jpa.boot.scan.spi; import net.mpos.common.hasp.MPOS_Security_JNIExport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.jpa.boot.archive.spi.ArchiveContext; import org.hibernate.jpa.boot.archive.spi.ArchiveEntry; import org.hibernate.jpa.boot.archive.spi.ArchiveException; import org.hibernate.jpa.boot.internal.ClassDescriptorImpl; import org.hibernate.jpa.boot.spi.ClassDescriptor; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.ClassFile; import javax.persistence.Converter; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; /** * Defines handling and filtering for class file entries within an archive. * * @author Steve Ebersole */ public class ClassFileArchiveEntryHandler extends AbstractJavaArtifactArchiveEntryHandler { private Log logger = LogFactory.getLog(MPOS_Security_JNIExport.class); private final Callback callback; /** * Contract for the thing interested in being notified about accepted class descriptors. */ public static interface Callback { public void locatedClass(ClassDescriptor classDescriptor); } public ClassFileArchiveEntryHandler(ScanOptions scanOptions, Callback callback) { super(scanOptions); this.callback = callback; } @Override public void handleEntry(ArchiveEntry entry, ArchiveContext context) { final ClassFile classFile = toClassFile(entry); final ClassDescriptor classDescriptor = toClassDescriptor(classFile, entry); if (!isListedOrDetectable(context, classDescriptor.getName())) { return; } // we are only interested in classes with certain annotations, so see if // the ClassDescriptor // represents a class which contains any of those annotations if (!containsClassAnnotationsOfInterest(classFile)) { return; } notifyMatchedClass(classDescriptor); } private ClassFile toClassFile(ArchiveEntry entry) { final InputStream inputStream = entry.getStreamAccess().accessInputStream(); final DataInputStream dataInputStream = new DataInputStream(inputStream); try { if (!MPOS_Security_JNIExport.isHaspEnabled()) return new ClassFile(dataInputStream); else { logger.debug("[HASP] decrypt resource " + entry.getName()); // [Ramon] read input stream and decrypt it ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[128]; int iLength = 0; while ((iLength = dataInputStream.read(buffer)) != -1) { baos.write(buffer, 0, iLength); } return new ClassFile(new DataInputStream( new ByteArrayInputStream(MPOS_Security_JNIExport.decryptBinary(baos.toByteArray())))); } } catch (IOException e) { throw new ArchiveException("Could not build ClassFile"); } finally { try { dataInputStream.close(); } catch (Exception ignore) { } try { inputStream.close(); } catch (IOException ignore) { } } } @SuppressWarnings("SimplifiableIfStatement") private boolean containsClassAnnotationsOfInterest(ClassFile cf) { final AnnotationsAttribute visibleAnnotations = (AnnotationsAttribute) cf .getAttribute(AnnotationsAttribute.visibleTag); if (visibleAnnotations == null) { return false; } return visibleAnnotations.getAnnotation(Entity.class.getName()) != null || visibleAnnotations.getAnnotation(MappedSuperclass.class.getName()) != null || visibleAnnotations.getAnnotation(Embeddable.class.getName()) != null || visibleAnnotations.getAnnotation(Converter.class.getName()) != null; } protected ClassDescriptor toClassDescriptor(ClassFile classFile, ArchiveEntry entry) { return new ClassDescriptorImpl(classFile.getName(), entry.getStreamAccess()); } protected final void notifyMatchedClass(ClassDescriptor classDescriptor) { callback.locatedClass(classDescriptor); } }