Source code: com/jguild/jrpm/io/RPMFile.java
1 /*
2 * jGuild Project: jRPM
3 * Released under the Apache License ( http://www.apache.org/LICENSE )
4 */
5 package com.jguild.jrpm.io;
6
7 import com.jguild.jrpm.io.datatype.DataTypeIf;
8 import com.jguild.jrpm.io.datatype.I18NSTRING;
9 import com.jguild.jrpm.io.datatype.STRING_ARRAY;
10 import com.jguild.jrpm.io.archive.CPIOPayloadArchive;
11
12 import org.apache.log4j.Logger;
13
14 import java.io.*;
15
16
17 /**
18 * This class allows IO access to an RPM file.
19 *
20 * @version $Id: RPMFile.java,v 1.19 2003/11/19 13:46:14 ymenager Exp $
21 */
22 public class RPMFile {
23 private static final Logger logger = Logger.getLogger(RPMFile.class);
24 private RPMHeader header;
25 private RPMLead lead;
26 private RPMSignature signature;
27 private int localePosition;
28 private PayloadArchive payload;
29 private long archiveOffset;
30 private File archiveFile;
31
32 /**
33 * Creates a new empty RPMFile object.
34 */
35 public RPMFile() {
36 }
37
38 /**
39 * Creates a new RPMFile object out of a file.
40 *
41 * @param fh The file object representing a rpm file
42 *
43 * @throws IOException if an error occurs during read of the rpm file
44 */
45 public RPMFile(File fh) throws IOException {
46 archiveFile = fh;
47 readFromStream(new BufferedInputStream(new FileInputStream(fh)));
48 }
49
50 /**
51 * Creates a new RPMFile object out of a input stream.
52 *
53 * @param rpmInputStream The input stream
54 *
55 * @throws IOException if an error occurs during read of the rpm file
56 */
57 public RPMFile(InputStream rpmInputStream) throws IOException {
58 readFromStream(rpmInputStream);
59 }
60
61 /**
62 * Get the header section of this rpm file.
63 *
64 * @return The rpm header
65 */
66 public RPMHeader getHeader() {
67 return header;
68 }
69
70 /**
71 * Get all known tags of this rpm file. This is equivalent to
72 * the --querytags option in rpm.
73 *
74 * @return An array of all tag names
75 */
76 public static String[] getKnownTagNames() {
77 return Header.getKnownTagNames();
78 }
79
80 /**
81 * Get the lead section of this rpm file
82 *
83 * @return The rpm lead
84 */
85 public RPMLead getLead() {
86 return lead;
87 }
88
89 /**
90 * Set the locale as int for all I18N strings that are
91 * returned by getTag(). The position has to correspond
92 * with the same position in the array returned by
93 * getLocales().
94 *
95 * @param pos The position in the array returned by getLocales().
96 */
97 public void setLocale(int pos) {
98 localePosition = pos;
99 }
100
101 /**
102 * Set the locale as string for all I18N strings that are
103 * returned by getTag(). The string must match with a string
104 * returned by getLocales().
105 *
106 * @param locale A locale matching a locale returned by getLocales()
107 * @throws IllegalArgumentException If the locale is not defined
108 * by getLocales().
109 */
110 public void setLocale(String locale) {
111 String[] locales = ((STRING_ARRAY) getTag("HEADERI18NTABLE")).getData();
112
113 for (int pos = 0; pos < locales.length; pos++) {
114 if (locales[pos].equals(locale)) {
115 setLocale(pos);
116
117 return;
118 }
119 }
120
121 throw new IllegalArgumentException("Unknown locale <" + locale + ">");
122 }
123
124 /**
125 * Return all known locales that are supported by this RPM file.
126 * The array is read out of the RPM file with the tag
127 * "HEADERI18NTABLE". The RPM has one entry for all I18N strings
128 * defined by this tag.
129 *
130 * @return A string array of all defined locales
131 */
132 public String[] getLocales() {
133 return ((STRING_ARRAY) getTag("HEADERI18NTABLE")).getData();
134 }
135
136 /**
137 * @param payloadArchive
138 *
139 * @todo implement RPMFile.setPayloadArchive(PayloadArchive)
140 */
141 public void setPayloadArchive(PayloadArchive payloadArchive) {
142 }
143
144 /**
145 * Get the archive as a CPIO Archive.
146 *
147 * @return CPIOPayloadArchiveArchive object.
148 * @throws IOException If an error happened reading the archive.
149 * @todo implement RPMFile.getPayloadArchive()
150 */
151 public PayloadArchive getPayloadArchive() throws IOException {
152 return null;
153 }
154
155 /**
156 * Get the signature section of this rpm file
157 *
158 * @return The rpm signature
159 */
160 public RPMSignature getSignature() {
161 return signature;
162 }
163
164 /**
165 * Get a tag by id as a Long
166 *
167 * @param tag A tag id as a Long
168 * @return A data struct containing the data of this tag
169 */
170 public DataTypeIf getTag(Long tag) {
171 DataTypeIf data = header.getTag(tag);
172
173 // set the locale for all I18N strings
174 if (data instanceof I18NSTRING) {
175 ((I18NSTRING) data).setLocaleIndex(localePosition);
176 }
177
178 return data;
179 }
180
181 /**
182 * Get a tag by id as a long
183 *
184 * @param tag A tag id as a long
185 * @return A data struct containing the data of this tag
186 */
187 public DataTypeIf getTag(long tag) {
188 return getTag(new Long(tag));
189 }
190
191 /**
192 * Get a tag by name
193 *
194 * @param tagname A tag name
195 * @return A data struct containing the data of this tag
196 */
197 public DataTypeIf getTag(String tagname) {
198 return getTag(getTagIdForName(tagname));
199 }
200
201 /**
202 * Read a tag with a given tag name.
203 *
204 * @param tagname A RPM tag name
205 * @return The id of the RPM tag
206 * @throws IllegalArgumentException if the tag name was not found
207 * @see Header#getTagIdForName(String)
208 */
209 public long getTagIdForName(String tagname) {
210 return header.getTagIdForName(tagname);
211 }
212
213 /**
214 * Get all tag ids contained in this rpm file.
215 *
216 * @return All tag ids contained in this rpm file.
217 */
218 public long[] getTagIds() {
219 return header.getTagIds();
220 }
221
222 /**
223 * Read a tag with a given tag id.
224 *
225 * @param tagid A RPM tag id
226 * @return The name of the RPM tag
227 * @throws IllegalArgumentException if the tag id was not found
228 * @see Header#getTagNameForId(long)
229 */
230 public String getTagNameForId(long tagid) {
231 return header.getTagNameForId(tagid);
232 }
233
234 /**
235 * Get all tag names contained in this rpm file.
236 *
237 * @return All tag names contained in this rpm file.
238 */
239 public String[] getTagNames() {
240 return getTagNames();
241 }
242
243 /**
244 * Read informations of a rpm file out of an input stream.
245 *
246 * @param rpmInputStream The input stream representing the rpm file
247 * @throws IOException if an error occurs during read of the rpm file
248 */
249 public void readFromStream(InputStream rpmInputStream)
250 throws IOException {
251 DataInputStream inputStream = new DataInputStream(rpmInputStream);
252
253 lead = new RPMLead(inputStream);
254 signature = new RPMSignature(inputStream);
255
256 if (logger.isDebugEnabled()) {
257 logger.debug("Signature Size: " + signature.getSize());
258 }
259
260 header = new RPMHeader(inputStream);
261
262 if (logger.isDebugEnabled()) {
263 logger.debug("Header Size: " + header.getSize());
264 }
265
266 if( archiveFile == null ) {
267 archiveFile = File.createTempFile("jrpmarch",null);
268 FileOutputStream archiveOuputStream = new FileOutputStream( archiveFile );
269 for( int i = inputStream.read() ; i != -1 ; i = inputStream.read() ) {
270 archiveOuputStream.write(i);
271 }
272 archiveOuputStream.close();
273 archiveFile.deleteOnExit();
274 archiveOffset = 0;
275 } else {
276 archiveOffset = lead.getSize() + signature.getSize() + header.getSize();
277 if (logger.isDebugEnabled()) {
278 logger.debug("Archive Offset: " + archiveOffset);
279 }
280 }
281 String payloadFormat = getTag("PAYLOADFORMAT").toString();
282 String payloadCompressor = getTag("PAYLOADCOMPRESSOR").toString();
283 if( payloadFormat.equals("cpio") ) {
284 byte compressor;
285 if( payloadCompressor.equals("gzip") ) {
286 compressor = PayloadArchive.COMPRESSION_GZIP;
287 } else if( payloadCompressor.equals("none") ) {
288 compressor = PayloadArchive.COMPRESSION_NONE;
289 } else {
290 throw new IOException("Unsupported compressor type "+payloadCompressor);
291 }
292 payload = new CPIOPayloadArchive(compressor,archiveFile,(int)archiveOffset);
293 } else {
294 throw new IOException("Unsupported Payload type "+payloadFormat);
295 }
296 inputStream.close();
297 }
298
299 /**
300 * Release locked resources.
301 */
302 public void close() {
303 if( archiveFile != null && archiveFile.exists() ) {
304 archiveFile.delete();
305 }
306 archiveFile = null;
307 header = null;
308 lead = null;
309 signature = null;
310 }
311
312 /**
313 * Write this rpm file to an output stream.
314 *
315 * @param rpmOutputStream Output stream to write the generated rpm.
316 * @todo implement write(OutputStream)
317 */
318 public void write(OutputStream rpmOutputStream) {
319 }
320
321 /**
322 * Extract this RPM file.
323 * @param basedir Base directory to extract the files to.
324 * @throws IOException If any I/O Exception happens.
325 */
326 public void extract( File basedir ) throws IOException {
327 if( payload == null ) {
328 throw new IOException("No payload in this rpm file");
329 }
330 payload.extract(basedir);
331 }
332 }