View Javadoc
1   package org.argeo.slc.repo;
2   
3   import static org.redline_rpm.header.Header.HeaderTag.HEADERIMMUTABLE;
4   import static org.redline_rpm.header.Signature.SignatureTag.SIGNATURES;
5   
6   import java.io.InputStream;
7   import java.nio.ByteBuffer;
8   import java.nio.channels.Channels;
9   
10  import javax.jcr.Node;
11  import javax.jcr.Property;
12  import javax.jcr.nodetype.NodeType;
13  
14  import org.apache.commons.io.FilenameUtils;
15  import org.argeo.slc.SlcException;
16  import org.argeo.slc.SlcNames;
17  import org.argeo.slc.SlcTypes;
18  import org.redline_rpm.ChannelWrapper.Key;
19  import org.redline_rpm.ReadableChannelWrapper;
20  import org.redline_rpm.header.AbstractHeader;
21  import org.redline_rpm.header.Format;
22  import org.redline_rpm.header.Header;
23  
24  /** Indexes an RPM file. */
25  public class RpmIndexer implements NodeIndexer, SlcNames {
26  	private Boolean force = false;
27  
28  	@Override
29  	public Boolean support(String path) {
30  		return FilenameUtils.getExtension(path).equals("rpm");
31  	}
32  
33  	@Override
34  	public void index(Node node) {
35  		try {
36  			if (!support(node.getPath()))
37  				return;
38  
39  			// Already indexed
40  			if (!force && node.isNodeType(SlcTypes.SLC_RPM))
41  				return;
42  
43  			if (!node.isNodeType(NodeType.NT_FILE))
44  				return;
45  
46  			InputStream in = node.getNode(Node.JCR_CONTENT)
47  					.getProperty(Property.JCR_DATA).getBinary().getStream();
48  			ReadableChannelWrapper channel = new ReadableChannelWrapper(
49  					Channels.newChannel(in));
50  			Format format = readRpmInfo(channel);
51  
52  			node.addMixin(SlcTypes.SLC_RPM);
53  			node.setProperty(SLC_NAME, readTag(format, Header.HeaderTag.NAME));
54  			String rpmVersion = readTag(format, Header.HeaderTag.VERSION);
55  			String rpmRelease = readTag(format, Header.HeaderTag.RELEASE);
56  			node.setProperty(SLC_RPM_VERSION, rpmVersion);
57  			node.setProperty(SLC_RPM_RELEASE, rpmRelease);
58  			node.setProperty(SLC_VERSION, rpmVersion + "-" + rpmRelease);
59  
60  			String arch = readTag(format, Header.HeaderTag.ARCH);
61  			if (arch != null)
62  				node.setProperty(SLC_RPM_ARCH, arch);
63  
64  			String archiveSize = readTag(format, Header.HeaderTag.ARCHIVESIZE);
65  			if (archiveSize != null)
66  				node.setProperty(SLC_RPM_ARCHIVE_SIZE,
67  						Long.parseLong(archiveSize));
68  
69  			node.getSession().save();
70  		} catch (Exception e) {
71  			throw new SlcException("Cannot index " + node, e);
72  		}
73  
74  	}
75  
76  	@SuppressWarnings("unused")
77  	public Format readRpmInfo(ReadableChannelWrapper channel) throws Exception {
78  		Format format = new Format();
79  
80  		Key<Integer> lead = channel.start();
81  		format.getLead().read(channel);
82  		// System.out.println( "Lead ended at '" + in.finish( lead) + "'.");
83  
84  		Key<Integer> signature = channel.start();
85  		int count = format.getSignature().read(channel);
86  		int expected = ByteBuffer
87  				.wrap((byte[]) format.getSignature().getEntry(SIGNATURES)
88  						.getValues(), 8, 4).getInt()
89  				/ -16;
90  		// System.out.println( "Signature ended at '" + in.finish( signature) +
91  		// "' and contained '" + count + "' headers (expected '" + expected +
92  		// "').");
93  
94  		Key<Integer> header = channel.start();
95  		count = format.getHeader().read(channel);
96  		expected = ByteBuffer.wrap(
97  				(byte[]) format.getHeader().getEntry(HEADERIMMUTABLE)
98  						.getValues(), 8, 4).getInt()
99  				/ -16;
100 		// System.out.println( "Header ended at '" + in.finish( header) +
101 		// " and contained '" + count + "' headers (expected '" + expected +
102 		// "').");
103 
104 		return format;
105 	}
106 
107 	private String readTag(Format format, Header.HeaderTag tag) {
108 		AbstractHeader.Entry<?> entry = format.getHeader().getEntry(tag);
109 		if (entry == null)
110 			return null;
111 		if (entry.getValues() == null)
112 			return null;
113 		Object[] values = (Object[]) entry.getValues();
114 		return values[0].toString().trim();
115 	}
116 }