|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.jaudiotagger.tag.id3.AbstractTagItem
org.jaudiotagger.tag.id3.AbstractTag
org.jaudiotagger.tag.id3.AbstractID3Tag
org.jaudiotagger.tag.id3.AbstractID3v2Tag
public abstract class AbstractID3v2Tag
This is the abstract base class for all ID3v2 tags.
Nested Class Summary | |
---|---|
(package private) class |
AbstractID3v2Tag.FrameAndSubId
This class had to be created to minimize the duplicate code in concrete subclasses of this class. |
Field Summary | |
---|---|
protected int |
duplicateBytes
|
protected java.lang.String |
duplicateFrameId
|
protected int |
emptyFrameBytes
|
java.util.HashMap |
encryptedFrameMap
Map of all encrypted frames, these cannot be unencrypted by jaudiotagger |
protected static int |
FIELD_TAG_FLAG_LENGTH
|
protected static int |
FIELD_TAG_FLAG_POS
|
protected static int |
FIELD_TAG_MAJOR_VERSION_LENGTH
|
protected static int |
FIELD_TAG_MAJOR_VERSION_POS
|
protected static int |
FIELD_TAG_MINOR_VERSION_LENGTH
|
protected static int |
FIELD_TAG_MINOR_VERSION_POS
|
protected static int |
FIELD_TAG_SIZE_LENGTH
|
protected static int |
FIELD_TAG_SIZE_POS
|
protected static int |
FIELD_TAGID_LENGTH
|
protected static int |
FIELD_TAGID_POS
|
protected int |
fileReadSize
|
java.util.HashMap |
frameMap
Map of all frames for this tag |
protected int |
invalidFrames
|
private static long |
MAXIMUM_WRITABLE_CHUNK_SIZE
|
static int |
TAG_HEADER_LENGTH
|
protected static byte[] |
TAG_ID
|
protected static int |
TAG_SIZE_INCREMENT
|
protected static java.lang.String |
TYPE_BODY
|
protected static java.lang.String |
TYPE_DUPLICATEBYTES
Holds count the number of bytes used up by invalid duplicate frames |
protected static java.lang.String |
TYPE_DUPLICATEFRAMEID
Holds the ids of invalid duplicate frames |
protected static java.lang.String |
TYPE_EMPTYFRAMEBYTES
Holds count the number bytes used up by empty frames |
protected static java.lang.String |
TYPE_FILEREADSIZE
Holds the size of the tag as reported by the tag header |
protected static java.lang.String |
TYPE_HEADER
|
protected static java.lang.String |
TYPE_INVALIDFRAMES
Holds count of invalid frames, (frames that could not be read) |
Fields inherited from class org.jaudiotagger.tag.id3.AbstractID3Tag |
---|
logger, TAG_RELEASE |
Fields inherited from class org.jaudiotagger.tag.id3.AbstractTag |
---|
TYPE_TAG |
Constructor Summary | |
---|---|
|
AbstractID3v2Tag()
Empty Constructor |
protected |
AbstractID3v2Tag(AbstractID3v2Tag copyObject)
This constructor is used when a tag is created as a duplicate of another tag of the same type and version. |
Method Summary | |
---|---|
void |
addField(Artwork artwork)
Create field and then set within tag itself |
void |
addField(FieldKey genericKey,
java.lang.String value)
Create the field based on the generic key and add it to the tag This is handled differently by different formats |
void |
addField(TagField field)
Add new field There is a special handling if adding another text field of the same type, in this case the value will be appended to the existing field, separated by the null character. |
protected abstract void |
addFrame(AbstractID3v2Frame frame)
|
private void |
addNewFrameOrAddField(java.util.List<TagField> list,
java.util.HashMap frameMap,
AbstractID3v2Frame existingFrame,
AbstractID3v2Frame frame)
Handles adding of a new field that's shares a frame with other fields, so modifies the existing frame rather than creating an ew frame for these special cases |
void |
adjustPadding(java.io.File file,
int paddingSize,
long audioStart)
Adjust the length of the padding at the beginning of the MP3 file, this is only called when there is currently not enough space before the start of the audio to write the tag. |
protected int |
calculateTagSize(int tagSize,
int audioStart)
This method determines the total tag size taking into account where the audio file starts, the size of the tagging data and user options for defining how tags should shrink or grow. |
protected void |
copyFrameIntoMap(java.lang.String id,
AbstractID3v2Frame newFrame)
|
protected void |
copyFrames(AbstractID3v2Tag copyObject)
Copy frames from another tag, |
protected void |
copyPrimitives(AbstractID3v2Tag copyObject)
Copy primitives apply to all tags |
TagField |
createField(FieldKey genericKey,
java.lang.String value)
Create a new TagField Only textual data supported at the moment. |
abstract AbstractID3v2Frame |
createFrame(java.lang.String id)
Create Frame of correct ID3 version with the specified id |
TagField |
createLinkedArtworkField(java.lang.String url)
Create a link to artwork, this is not recommended because the link may be broken if the mp3 or image file is moved |
void |
createStructure()
|
void |
createStructureBody()
|
void |
createStructureHeader()
|
void |
delete(java.io.RandomAccessFile file)
Delete Tag |
void |
deleteArtworkField()
Delete all instance of artwork Field |
void |
deleteField(FieldKey genericKey)
Delete fields with this generic key |
protected TagField |
doCreateTagField(AbstractID3v2Tag.FrameAndSubId formatKey,
java.lang.String value)
Create Frame for Id3 Key Only textual data supported at the moment, should only be used with frames that support a simple string argument. |
protected void |
doDeleteTagField(AbstractID3v2Tag.FrameAndSubId formatKey)
Internal delete method |
protected java.lang.String |
doGetValueAtIndex(AbstractID3v2Tag.FrameAndSubId formatKey,
int index)
|
boolean |
equals(java.lang.Object obj)
Is this tag equivalent to another |
int |
getDuplicateBytes()
Returns the number of bytes which come from duplicate frames |
java.lang.String |
getDuplicateFrameId()
Return the string which holds the ids of all duplicate frames. |
int |
getEmptyFrameBytes()
Returns the number of bytes which come from empty frames |
java.lang.Object |
getEncryptedFrame(java.lang.String identifier)
Return any encrypted frames with this identifier |
int |
getFieldCount()
Count number of frames/fields in this tag |
int |
getFieldCountIncludingSubValues()
Return count of fields, this considers a text frame with two null separated values as two fields, if you want a count of frames @see getFrameCount |
java.util.Iterator<TagField> |
getFields()
Iterator over all the fields within the tag, handle multiple fields with the same id |
java.util.List<TagField> |
getFields(FieldKey genericKey)
Get field(s) for this key |
java.util.List<TagField> |
getFields(java.lang.String id)
Retrieve the values that exists for this id3 frame id |
protected java.nio.channels.FileLock |
getFileLockForWriting(java.nio.channels.FileChannel fileChannel,
java.lang.String filePath)
Get file lock for writing too file TODO:this appears to have little effect on Windows Vista |
int |
getFileReadBytes()
Returns the tag size as reported by the tag header |
java.lang.String |
getFirst(FieldKey genericKey)
Retrieve the first value that exists for this generic key |
java.lang.String |
getFirst(java.lang.String identifier)
Retrieve the first value that exists for this identifier If the value is a String it returns that, otherwise returns a summary of the fields information |
Artwork |
getFirstArtwork()
|
TagField |
getFirstField(FieldKey genericKey)
|
AbstractID3v2Frame |
getFirstField(java.lang.String identifier)
Retrieve the first tag field that exists for this identifier |
java.lang.Object |
getFrame(java.lang.String identifier)
For single frames return the frame in this tag with given identifier if it exists, if multiple frames exist with the same identifier it will return a list containing all the frames with this identifier Warning the match is only done against the identifier so if a tag contains a frame with an unsupported body but happens to have an identifier that is valid for another version of the tag it will be returned. |
protected abstract AbstractID3v2Tag.FrameAndSubId |
getFrameAndSubIdFromGenericKey(FieldKey genericKey)
|
java.util.Iterator |
getFrameOfType(java.lang.String identifier)
Return all frames which start with the identifier, this can be more than one which is useful if trying to retrieve similar frames e.g TIT1,TIT2,TIT3 ... |
protected abstract ID3Frames |
getID3Frames()
|
int |
getInvalidFrames()
Return byte count of invalid frames |
abstract java.util.Comparator |
getPreferredFrameOrderComparator()
|
int |
getSize()
Return tag size based upon the sizes of the tags rather than the physical no of bytes between start of ID3Tag and start of Audio Data.Should be extended by subclasses to include header. |
java.lang.String |
getSubValue(FieldKey genericKey,
int n,
int m)
Retrieve the mth value that exists in the nth frame for this generic key |
private java.lang.String |
getTextValueForFrame(AbstractID3v2Frame frame)
|
static long |
getV2TagSizeIfExists(java.io.File file)
Checks to see if the file contains an ID3tag and if so return its size as reported in the tag header and return the size of the tag (including header), if no such tag exists return zero. |
java.lang.String |
getValue(FieldKey genericKey,
int index)
Retrieve the value that exists for this generic key and this index Have to do some special mapping for certain generic keys because they share frame with another generic key. |
boolean |
hasCommonFields()
Returns true , if at least one of the contained
fields is a common field (TagField.isCommon() ). |
boolean |
hasField(java.lang.String id)
Does this tag contain a field with the specified id |
boolean |
hasFrame(java.lang.String identifier)
Return whether tag has frame with this identifier Warning the match is only done against the identifier so if a tag contains a frame with an unsuported body but happens to have an identifier that is valid for another version of the tag it will return true |
boolean |
hasFrameAndBody(java.lang.String identifier)
Return whether tag has frame with this identifier and a related body. |
boolean |
hasFrameOfType(java.lang.String identifier)
Return whether tag has frame starting with this identifier Warning the match is only done against the identifier so if a tag contains a frame with an unsupported body but happens to have an identifier that is valid for another version of the tag it will return true |
boolean |
isEmpty()
Is this tag empty |
java.util.Iterator |
iterator()
Return the frames in the order they were added |
protected void |
loadFrameIntoMap(java.lang.String frameId,
AbstractID3v2Frame next)
Add frame to the frame map |
protected void |
loadFrameIntoSpecifiedMap(java.util.HashMap map,
java.lang.String frameId,
AbstractID3v2Frame next)
Decides what to with the frame that has just been read from file. |
void |
mergeDuplicateFrames(AbstractID3v2Frame newFrame,
java.util.List<AbstractID3v2Frame> frames)
Add frame taking into account existing frames of the same type |
void |
removeFrame(java.lang.String identifier)
Remove frame(s) with this identifier from tag |
void |
removeFrameOfType(java.lang.String identifier)
Remove any frames starting with this identifier from tag |
void |
removeUnsupportedFrames()
Remove all frame(s) which have an unsupported body, in other words remove all frames that are not part of the standard frameSet for this tag |
private void |
replaceFile(java.io.File originalFile,
java.io.File newFile)
Replace originalFile with the contents of newFile Both files must exist in the same folder so that there are no problems with filesystem mount points |
boolean |
seek(java.nio.ByteBuffer byteBuffer)
Does a tag of the correct version exist in this file. |
boolean |
setEncoding(java.lang.String enc)
|
void |
setField(Artwork artwork)
Create field and then set within tag itself |
void |
setField(FieldKey genericKey,
java.lang.String value)
Create the field based on the generic key and set it in the tag |
void |
setField(TagField field)
Sets a field in the structure, used internally by the library |
void |
setFrame(AbstractID3v2Frame frame)
Add a frame to this tag |
void |
setFrame(java.lang.String identifier,
java.util.List<AbstractID3v2Frame> multiFrame)
Used for setting multiple frames for a single frame Identifier Warning if frame(s) already exists for this identifier thay are overwritten TODO needs to ensure do not add an invalid frame for this tag |
void |
write(java.io.File file,
long audioStartByte)
Write tag to file. |
void |
write(java.io.RandomAccessFile file)
Write tag to file. |
void |
write(java.nio.channels.WritableByteChannel channel)
Write tag to channel. |
protected void |
writeBufferToFile(java.io.File file,
java.nio.ByteBuffer headerBuffer,
byte[] bodyByteBuffer,
int padding,
int sizeIncPadding,
long audioStartLocation)
Write the data from the buffer to the file |
protected java.io.ByteArrayOutputStream |
writeFramesToBuffer()
Write all the frames to the byteArrayOutputStream |
private void |
writeFramesToBufferStream(java.util.Map map,
java.io.ByteArrayOutputStream bodyBuffer)
Write frames in map to bodyBuffer |
Methods inherited from class org.jaudiotagger.tag.id3.AbstractID3Tag |
---|
getIdentifier, getLoggingFilename, getMajorVersion, getRelease, getRevision, setLoggingFilename, toString |
Methods inherited from class org.jaudiotagger.tag.id3.AbstractTagItem |
---|
isSubsetOf, read |
Methods inherited from class java.lang.Object |
---|
clone, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Methods inherited from interface org.jaudiotagger.tag.Tag |
---|
createField, deleteField, getArtworkList, toString |
Field Detail |
---|
protected static final java.lang.String TYPE_HEADER
protected static final java.lang.String TYPE_BODY
protected static final byte[] TAG_ID
public static final int TAG_HEADER_LENGTH
protected static final int FIELD_TAGID_LENGTH
protected static final int FIELD_TAG_MAJOR_VERSION_LENGTH
protected static final int FIELD_TAG_MINOR_VERSION_LENGTH
protected static final int FIELD_TAG_FLAG_LENGTH
protected static final int FIELD_TAG_SIZE_LENGTH
protected static final int FIELD_TAGID_POS
protected static final int FIELD_TAG_MAJOR_VERSION_POS
protected static final int FIELD_TAG_MINOR_VERSION_POS
protected static final int FIELD_TAG_FLAG_POS
protected static final int FIELD_TAG_SIZE_POS
protected static final int TAG_SIZE_INCREMENT
private static final long MAXIMUM_WRITABLE_CHUNK_SIZE
public java.util.HashMap frameMap
public java.util.HashMap encryptedFrameMap
protected static final java.lang.String TYPE_DUPLICATEFRAMEID
protected java.lang.String duplicateFrameId
protected static final java.lang.String TYPE_DUPLICATEBYTES
protected int duplicateBytes
protected static final java.lang.String TYPE_EMPTYFRAMEBYTES
protected int emptyFrameBytes
protected static final java.lang.String TYPE_FILEREADSIZE
protected int fileReadSize
protected static final java.lang.String TYPE_INVALIDFRAMES
protected int invalidFrames
Constructor Detail |
---|
public AbstractID3v2Tag()
protected AbstractID3v2Tag(AbstractID3v2Tag copyObject)
copyObject
- Method Detail |
---|
protected void copyPrimitives(AbstractID3v2Tag copyObject)
copyObject
- protected void copyFrames(AbstractID3v2Tag copyObject)
copyObject
- protected abstract void addFrame(AbstractID3v2Frame frame)
public int getDuplicateBytes()
public java.lang.String getDuplicateFrameId()
public int getEmptyFrameBytes()
public int getInvalidFrames()
public int getFileReadBytes()
public boolean hasFrame(java.lang.String identifier)
identifier
- frameId to lookup
public boolean hasFrameAndBody(java.lang.String identifier)
identifier
- frameId to lookup
public boolean hasFrameOfType(java.lang.String identifier)
identifier
- start of frameId to lookup
public java.lang.Object getFrame(java.lang.String identifier)
identifier
- is an ID3Frame identifier
public java.lang.Object getEncryptedFrame(java.lang.String identifier)
For single frames return the frame in this tag with given identifier if it exists, if multiple frames exist with the same identifier it will return a list containing all the frames with this identifier
identifier
-
public java.lang.String getFirst(java.lang.String identifier)
getFirst
in interface Tag
identifier
-
private java.lang.String getTextValueForFrame(AbstractID3v2Frame frame)
frame
-
public TagField getFirstField(FieldKey genericKey) throws KeyNotFoundException
getFirstField
in interface Tag
KeyNotFoundException
public AbstractID3v2Frame getFirstField(java.lang.String identifier)
getFirstField
in interface Tag
identifier
-
public void setFrame(AbstractID3v2Frame frame)
frame
- the frame to add
Warning if frame(s) already exists for this identifier that they are overwritten
protected abstract ID3Frames getID3Frames()
public void setField(FieldKey genericKey, java.lang.String value) throws KeyNotFoundException, FieldDataInvalidException
Tag
setField
in interface Tag
KeyNotFoundException
FieldDataInvalidException
public void addField(FieldKey genericKey, java.lang.String value) throws KeyNotFoundException, FieldDataInvalidException
Tag
addField
in interface Tag
KeyNotFoundException
FieldDataInvalidException
public void mergeDuplicateFrames(AbstractID3v2Frame newFrame, java.util.List<AbstractID3v2Frame> frames)
newFrame
- frames
- private void addNewFrameOrAddField(java.util.List<TagField> list, java.util.HashMap frameMap, AbstractID3v2Frame existingFrame, AbstractID3v2Frame frame)
list
- frameMap
- existingFrame
- frame
- public void setField(TagField field) throws FieldDataInvalidException
Tag
setField
in interface Tag
field
-
FieldDataInvalidException
public void addField(TagField field) throws FieldDataInvalidException
addField
in interface Tag
field
-
FieldDataInvalidException
public void setFrame(java.lang.String identifier, java.util.List<AbstractID3v2Frame> multiFrame)
identifier
- multiFrame
- public java.util.Iterator getFrameOfType(java.lang.String identifier)
identifier
-
public void delete(java.io.RandomAccessFile file) throws java.io.IOException
delete
in class AbstractTag
file
- to delete the tag from
java.io.IOException
- if problem accessing the file
public boolean equals(java.lang.Object obj)
equals
in class AbstractTag
obj
- to test for equivalence
public java.util.Iterator iterator()
iterator
in class AbstractTag
public void removeFrame(java.lang.String identifier)
identifier
- frameId to look forpublic void removeUnsupportedFrames()
public void removeFrameOfType(java.lang.String identifier)
identifier
- start of frameId to look forpublic void write(java.io.File file, long audioStartByte) throws java.io.IOException
file
- audioStartByte
-
java.io.IOException
- TODO should be abstractprotected java.nio.channels.FileLock getFileLockForWriting(java.nio.channels.FileChannel fileChannel, java.lang.String filePath) throws java.io.IOException
fileChannel
- filePath
-
java.io.IOException
- if unable to get lock because already locked by another program
java.nio.channels.OverlappingFileLockException
- if already locked by another thread in the same VM, we dont catch this
because indicates a programming errorpublic void write(java.io.RandomAccessFile file) throws java.io.IOException
write
in class AbstractTag
file
-
java.io.IOException
- TODO should be abstractpublic void write(java.nio.channels.WritableByteChannel channel) throws java.io.IOException
channel
-
java.io.IOException
- TODO should be abstractpublic static long getV2TagSizeIfExists(java.io.File file) throws java.io.IOException
file
-
java.io.IOException
public boolean seek(java.nio.ByteBuffer byteBuffer)
seek
in class AbstractTag
byteBuffer
- to search through
protected int calculateTagSize(int tagSize, int audioStart)
tagSize
- audioStart
-
public void adjustPadding(java.io.File file, int paddingSize, long audioStart) throws java.io.FileNotFoundException, java.io.IOException
ID3v2
tag.
The old file will be deleted, and the new file renamed.
paddingSize
- This is total size required to store tag before audioaudioStart
- file
- The file to adjust the padding length of
java.io.FileNotFoundException
- if the file exists but is a directory
rather than a regular file or cannot be opened for any other
reason
java.io.IOException
- on any I/O errorprotected void writeBufferToFile(java.io.File file, java.nio.ByteBuffer headerBuffer, byte[] bodyByteBuffer, int padding, int sizeIncPadding, long audioStartLocation) throws java.io.IOException
file
- headerBuffer
- bodyByteBuffer
- padding
- sizeIncPadding
- audioStartLocation
-
java.io.IOException
private void replaceFile(java.io.File originalFile, java.io.File newFile) throws java.io.IOException
newFile
- originalFile
-
java.io.IOException
protected void copyFrameIntoMap(java.lang.String id, AbstractID3v2Frame newFrame)
protected void loadFrameIntoMap(java.lang.String frameId, AbstractID3v2Frame next)
frameId
- next
- protected void loadFrameIntoSpecifiedMap(java.util.HashMap map, java.lang.String frameId, AbstractID3v2Frame next)
frameId
- next
- public int getSize()
getSize
in class AbstractTagItem
protected java.io.ByteArrayOutputStream writeFramesToBuffer() throws java.io.IOException
Currently Write all frames, defaults to the order in which they were loaded, newly created frames will be at end of tag.
java.io.IOException
private void writeFramesToBufferStream(java.util.Map map, java.io.ByteArrayOutputStream bodyBuffer) throws java.io.IOException
map
- bodyBuffer
-
java.io.IOException
public abstract java.util.Comparator getPreferredFrameOrderComparator()
public void createStructure()
public void createStructureHeader()
public void createStructureBody()
public java.util.List<TagField> getFields(java.lang.String id) throws KeyNotFoundException
getFields
in interface Tag
id
- The field id.
TagField
objects with the given "id".
KeyNotFoundException
public abstract AbstractID3v2Frame createFrame(java.lang.String id)
id
-
public boolean hasCommonFields()
Tag
true
, if at least one of the contained
fields is a common field (TagField.isCommon()
).
hasCommonFields
in interface Tag
true
if a common
field is present.public boolean hasField(java.lang.String id)
hasField
in interface Tag
id
- The field id to look for.
true
if tag contains a TagField
with the
given id.Tag.hasField(java.lang.String)
public boolean isEmpty()
isEmpty
in interface Tag
true
if tag contains no field.Tag.isEmpty()
public java.util.Iterator<TagField> getFields()
Tag
getFields
in interface Tag
public int getFieldCount()
getFieldCount
in interface Tag
public int getFieldCountIncludingSubValues()
getFieldCountIncludingSubValues
in interface Tag
public boolean setEncoding(java.lang.String enc) throws FieldDataInvalidException
setEncoding
in interface Tag
FieldDataInvalidException
public java.lang.String getFirst(FieldKey genericKey) throws KeyNotFoundException
getFirst
in interface Tag
genericKey
-
KeyNotFoundException
public java.lang.String getSubValue(FieldKey genericKey, int n, int m)
getSubValue
in interface Tag
genericKey
- n
- the index of the framem
-
public java.lang.String getValue(FieldKey genericKey, int index) throws KeyNotFoundException
getValue
in interface Tag
genericKey
-
KeyNotFoundException
public TagField createField(FieldKey genericKey, java.lang.String value) throws KeyNotFoundException, FieldDataInvalidException
createField
in interface Tag
genericKey
- is the generic keyvalue
- to store
KeyNotFoundException
FieldDataInvalidException
protected TagField doCreateTagField(AbstractID3v2Tag.FrameAndSubId formatKey, java.lang.String value) throws KeyNotFoundException, FieldDataInvalidException
formatKey
- value
-
KeyNotFoundException
FieldDataInvalidException
protected java.lang.String doGetValueAtIndex(AbstractID3v2Tag.FrameAndSubId formatKey, int index) throws KeyNotFoundException
formatKey
- index
-
KeyNotFoundException
public TagField createLinkedArtworkField(java.lang.String url)
url
- specifies the link, it could be a local file or could be a full url
public void deleteField(FieldKey genericKey) throws KeyNotFoundException
deleteField
in interface Tag
genericKey
-
KeyNotFoundException
protected void doDeleteTagField(AbstractID3v2Tag.FrameAndSubId formatKey) throws KeyNotFoundException
formatKey
-
KeyNotFoundException
protected abstract AbstractID3v2Tag.FrameAndSubId getFrameAndSubIdFromGenericKey(FieldKey genericKey)
public java.util.List<TagField> getFields(FieldKey genericKey) throws KeyNotFoundException
getFields
in interface Tag
genericKey
-
KeyNotFoundException
public Artwork getFirstArtwork()
getFirstArtwork
in interface Tag
public void setField(Artwork artwork) throws FieldDataInvalidException
setField
in interface Tag
artwork
-
FieldDataInvalidException
public void addField(Artwork artwork) throws FieldDataInvalidException
addField
in interface Tag
artwork
-
FieldDataInvalidException
public void deleteArtworkField() throws KeyNotFoundException
deleteArtworkField
in interface Tag
KeyNotFoundException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |