Thursday, December 6

Applets in Java


Where Do Applets and Classes Come from?
When a web browser sees an applet tag and decides to download and play the applet,
it starts a long chain of events. Let's say your browser sees the following applet tag:

<APPLET codebase="http://metalab.unc.edu/javafaq/classes"
code="Animation.class" width="200" height="100" >
<PARAM NAME = “FRAMErATE”   VALUE = “10”>
</APPLET>

1.      The web browser sets aside a rectangular area on the page 200 pixels wide and
100 pixels high. In most web browsers, this area has a fixed size and cannot be
modified once created. The appletviewer in the JDK is a notable exception.
2.      The browser opens a connection to the server specified in the codebase parameter, using port 80 unless another port is specified in the codebase URL. If there's no codebase parameter, then the browser connects to the same server that served the HTML page.
3.      The browser requests the .class file from the web server as it requests any other file. If a codebase is present, it is prefixed to the requested filename. Otherwise, the document base (the directory that contains the HTML page) is used. For example:
GET /javafaq/classes/Animation.class HTTP 1.0

4.      The server responds by sending a MIME header followed by a blank line (\r\n) followed by the binary data in the .class file. A properly configured server sends .class files with MIME type application/octet-stream. For example:
HTTP 1.0 200 OK
Date: Mon, 10 Jun 1999 17:11:43 GMT
Server: Apache/1.2.8
Content-type: application/octet-stream
Content-length: 2782
Last-modified: Fri, 08 Sep 1998 21:53:55 GMT
5.      The web browser receives the data and stores it in a byte array. The byte code verifier goes over the byte codes that have been received to make sure they don't do anything forbidden, such as converting an integer into a pointer.
6.      If the byte code verifier is satisfied with the bytes that were downloaded, then the raw data is converted into a Java class using the defineClass( ) and loadClass( ) methods of the current ClassLoader object.
7.      The web browser instantiates the Animation class using its noargs constructor.
8.      The web browser invokes the init( ) method of Animation.
9.       The web browser invokes the start( ) method of Animation.

10.  If the Animation class references another class, the Java interpreter first searches for
the new class in the user's CLASSPATH. If the class is found in the user's CLASSPATH,
then it is created from the .class file on the user's hard drive. Otherwise the web
browser goes back to the site from which this class came and downloads the .class file for the new class. The same procedure is followed for the new class and any other
class that is downloaded from the Net. If the new class cannot be found, a
ClassNotFoundException is thrown



Who Can an Applet Talk to and What Can It Say?

1.      Applets cannot access arbitrary addresses in memory. Unlike the other restrictions in the list, which are enforced by the browser's SecurityManager instance, this restriction is a property of the Java language itself and the byte code verifier.
2.      Applets cannot access the local filesystem in any way. They cannot read from or write to the local filesystem nor can they find out any information about files. Therefore, they cannot find out whether a file exists or what its modification date may be.
3.      Applets cannot launch other programs on the client. In other words, they
cannot call System.exec( ) or Runtime.exec( ).
4.      Applets cannot load native libraries or define native method calls.
5.      Applets are not allowed to use System.getProperty( ) in a way that reveals
information about the user or the user's machine, such as a username or home
directory. They may use System.getProperty( ) to find out what version of
Java is in use.
6.       Applets may not define any system properties.
7.      In Java 1.1 and later, applets may not create or manipulate any Thread or
ThreadGroup that is not in the applet's own ThreadGroup. They may do this
in Java 1.0.
8.       Applets cannot define or use a new instance of ClassLoader, SecurityManager, ContentHandlerFactory, SocketImplFactory, or URLStreamHandlerFactory. They must use the ones already in place.

9.      An applet can only open network connections to the host from which the applet itself was downloaded.
10.  An applet cannot listen on ports below 1,024. (Internet Explorer 5.0 doesn't
allow applets to listen on any ports.)
11.  Even if an applet can listen on a port, it can accept incoming connections only
from the host from which the applet itself was downloaded.

Thread Scheduling And Socket


1.      Thread Scheduling
There are two kinds of thread scheduling, preemptive and cooperative.
  • A preemptive thread scheduler determines when a thread has had its fair share of CPU time, pauses that thread, and then hands off control of the CPU to a different thread.
  • A cooperative thread scheduler waits for the running thread to pause itself before handing off control of the CPU to a different thread.
  • A virtual machine that uses cooperative thread scheduling is much more susceptible to thread starvation than a virtual machine that uses preemptive thread scheduling.
2.      Synchronization, wait(), notify(), notifyAll()
Monitor objects maintain a list of all threads waiting to enter the monitor object to execute synchronized methods. A thread is inserted in the list and waits for the object if that thread calls a synchronized method of the object while another thread is already executing in a synchronized method of that object. A thread also is inserted in the list if the thread calls wait while operating inside the object. However, it is important to distinguish between waiting threads that blocked because the monitor was busy and threads that explicitly called wait inside the monitor. Upon completion of a synchronized method, outside threads that blocked because the monitor was busy can proceed to enter the object. Threads that explicitly invoked wait can proceed only when notified via a call by another thread to notify or notifyAll. When it is acceptable for a waiting thread to proceed, the scheduler selects the thread with the highest priority.


A socket is a connection between two hosts. It can perform seven basic operations:

·         Connect to a remote machine
·         Send data
·         Receive data
·         Close a connection
·         Bind to a port
·         Listen for incoming data
·         Accept connections from remote machines on the bound port

Client Sockets
·         The program creates a new socket with a Socket( ) constructor.
·         The socket attempts to connect to the remote host.
·         Once the connection is established, the local and remote hosts get input and output streams from the socket and use those streams to send data to each other.
·         This connection is full-duplex; both hosts can send and receive data simultaneously.
·         What the data means depends on the protocol; different commands are sent to an FTP server than to an HTTP server. There will normally be some agreed-upon hand-shaking followed by the transmission of data from one to the other.
·         When the transmission of data is complete, one or both sides close the connection. Some protocols, such as HTTP 1.0, require the connection to be closed after each request is serviced. Others, such as FTP, allow multiple requests to be processed in a single connection.

Threads


1.      Threads are subtasks in a program that can be in execution concurrently.
2.      The concurrency that computers perform today is normally implemented as operating system primitives” available only to highly experienced “systems programmers.”
3.      Java makes concurrency primitives available to the programmer.
4.      Subclass the Thread class and override its run( ) method.
5.      implement the Runnable interface and pass the Runnable object to the Thread constructor. Runnable has one method run().
6.      Signature of function: public void run( )
7.      run method may invoke other methods; it may construct other objects; it may even spawn other threads. The thread starts here and it stops here. When the run( ) method completes, the thread dies.
8.      the run( ) method is to a thread what the main( )method is to a traditional nonthreaded program.
9.      A single-threaded program exits when the main( ) method returns.
10.  A multithreaded program exits when both the main( ) method and the run( ) methods of all nondaemon threads return. (Daemon threads perform background tasks such as garbage collection and don't prevent the virtual machine from exiting.)
11.  Extending Thread Class
class A extends Thread
{
public static void main (String[] args)
{
Thread t = new A();
t.start( );
}
public void run()
{
//details
}
}

12.  Implementing Runnable:

class A implements Runnable
{
public static void main (String[] args)
{
A a = new A();
Thread t = new Thread(a);
t.start( );
}
public void run()
{
//details
}
}

13.  Passing Information to Thread.
14.  Returning Information from Thread.
15.  Avoid Race Condition.
16.  A thread specified as daemon will cease execution when the thread that created it ends. Syntax: threadName.setDaemon(true);
17.  A thread that is not daemon is called a user thread.
18.  Synchronized methods
public synchronized void writeEntry(String message)
19.  Every object that has synchronized methods has a monitor. The monitor lets only one thread at a time execute a synchronized method on the object.
20.  Only one synchronized instance method for an object can execute at any given time. Only one synchronized static method for a class can execute at one time.

21.  Synchronized Blocks
A code block can be declared as a synchronized on an object. Only one synchronized code block for an object can execute at any given time.
synchronized (System.out)
{
System.out.print(input + ": ");
for (int i = 0; i < digest.length; i++)
{
System.out.print(digest[i] + " ");
}
System.out.println( );
}
22.  Thread Scheduling
  • All important threads get at least some time to run and that the more important threads get more time.
  • Threads should execute in a reasonable order.(e.g. not in series)
  • Thread should not suffer through starvation.
23.  Thread Priority
  • Priority is specified as an integer ranging from 1(lowest) to 10(highest).
  • When multiple threads are able to run, generally the VM will run only the highest-priority thread,
  • public final void setPriority(int newPriority)
  • public final int getPriority( )

24.  Suspension of Thread
There are 10 ways a thread can pause in favor of other threads or indicate that it is ready to pause. These are:
  • It can block on I/O.
  • It can block on a synchronized object.
A thread can wait on an object it has locked. While waiting, it releases the lock on the object and pauses until it is notified by some other thread. Another thread changes the object in some way, notifies the thread waiting on that object, and then continues.
  • It can yield.
  • It can go to sleep.
A thread that goes to sleep does hold onto all the locks it's grabbed. Consequently, other threads that need the same locks will be blocked even if the CPU is available.

  • It can join another thread.
  • It can wait on an object.
  • It can finish.
There's a nontrivial amount of overhead for the virtual machine in setting up and tearing down threads.
  • It can be preempted by a higher-priority thread.
  • It can be suspended.
It can stop.

Sunday, November 4

Crystal Reporting (WPF Application + MYSQL Database) Complete Guide


to generate crystal report in wpf c# application is little difficult. first of all read all requirements about platform you are using. Make sure that you have added following assemblies.


Platform:
Windows 7 64bit
WPF application
MYSQL database
MYSQL ODBC connector 32bit

make sure you have installed MYSQL ODBC connector. if there is mismatch of driver and application let say mysql ODBC is 64Bit/32Bit and wpf application is off 32Bit/64bit repectively then you will face this mismatch issue. to resolve this go to C:\Windows\SysWOW64 and run odbcad32.exe file if you have installed MYSQL ODBC connector 32bit on your PC. now create datasource like this:




now open visual studio and create wpf application. add crystal report on your project. as crystal report viewer os windows form component. go to Project from menu bar. click on project properties. and set target framework to .NET framework 4. now add xml in your window tag of WPF.
xmlns:winform="clr-namespace:CrystalDecisions.Windows.Forms;assembly=CrystalDecisions.Windows.Forms"

in your grid tag

        <WindowsFormsHost Margin="0,12,0,0" Name="windowsFormsHost1">
            <winform:CrystalReportViewer x:Name="rptviewer" />
        </WindowsFormsHost>
and now create crystal report on your project.

















create an instance of your crystal report like this:
          
   CrystalReport1 e = new CrystalReport1();
            rptviewer.ReportSource = e;











Wednesday, October 31

Calculator in WPF application C#.NET

C# Code:
Download here: source code
Concatenate of two numbers:





namespace calculator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            string numberBTN  = String.Concat(button1.Content.ToString(), textBox1.Text);
            textBox1.Text = numberBTN;
        }
    }
}

XAML COde:



<Window x:Class="calculator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Calculator" Height="350" Width="525">
    <Grid>
        <TextBox Height="27" HorizontalAlignment="Center" Margin="153,35,0,0" Name="textBox1" VerticalAlignment="Top" Width="200" />
        <Button Content="1" Height="23" Margin="234,109,0,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="36" Click="button1_Click" />
    </Grid>
</Window>

Monday, October 29

Applets in Java


Applets

Where Do Applets and Classes Come from?
When a web browser sees an applet tag and decides to download and play the applet,
it starts a long chain of events. Let's say your browser sees the following applet tag:

<APPLET codebase="http://metalab.unc.edu/javafaq/classes"
code="Animation.class" width="200" height="100" >
<PARAM NAME = “FRAMErATE”   VALUE = “10”>
</APPLET>

1.      The web browser sets aside a rectangular area on the page 200 pixels wide and
100 pixels high. In most web browsers, this area has a fixed size and cannot be
modified once created. The appletviewer in the JDK is a notable exception.
2.      The browser opens a connection to the server specified in the codebase parameter, using port 80 unless another port is specified in the codebase URL. If there's no codebase parameter, then the browser connects to the same server that served the HTML page.
3.      The browser requests the .class file from the web server as it requests any other file. If a codebase is present, it is prefixed to the requested filename. Otherwise, the document base (the directory that contains the HTML page) is used. For example:
GET /javafaq/classes/Animation.class HTTP 1.0

4.      The server responds by sending a MIME header followed by a blank line (\r\n) followed by the binary data in the .class file. A properly configured server sends .class files with MIME type application/octet-stream. For example:
HTTP 1.0 200 OK
Date: Mon, 10 Jun 1999 17:11:43 GMT
Server: Apache/1.2.8
Content-type: application/octet-stream
Content-length: 2782
Last-modified: Fri, 08 Sep 1998 21:53:55 GMT
5.      The web browser receives the data and stores it in a byte array. The byte code verifier goes over the byte codes that have been received to make sure they don't do anything forbidden, such as converting an integer into a pointer.
6.      If the byte code verifier is satisfied with the bytes that were downloaded, then the raw data is converted into a Java class using the defineClass( ) and loadClass( ) methods of the current ClassLoader object.
7.      The web browser instantiates the Animation class using its noargs constructor.
8.      The web browser invokes the init( ) method of Animation.
9.       The web browser invokes the start( ) method of Animation.

10.  If the Animation class references another class, the Java interpreter first searches for
the new class in the user's CLASSPATH. If the class is found in the user's CLASSPATH,
then it is created from the .class file on the user's hard drive. Otherwise the web
browser goes back to the site from which this class came and downloads the .class file for the new class. The same procedure is followed for the new class and any other
class that is downloaded from the Net. If the new class cannot be found, a
ClassNotFoundException is thrown



Who Can an Applet Talk to and What Can It Say?

1.      Applets cannot access arbitrary addresses in memory. Unlike the other restrictions in the list, which are enforced by the browser's SecurityManager instance, this restriction is a property of the Java language itself and the byte code verifier.
2.      Applets cannot access the local filesystem in any way. They cannot read from or write to the local filesystem nor can they find out any information about files. Therefore, they cannot find out whether a file exists or what its modification date may be.
3.      Applets cannot launch other programs on the client. In other words, they
cannot call System.exec( ) or Runtime.exec( ).
4.      Applets cannot load native libraries or define native method calls.
5.      Applets are not allowed to use System.getProperty( ) in a way that reveals
information about the user or the user's machine, such as a username or home
directory. They may use System.getProperty( ) to find out what version of
Java is in use.
6.       Applets may not define any system properties.
7.      In Java 1.1 and later, applets may not create or manipulate any Thread or
ThreadGroup that is not in the applet's own ThreadGroup. They may do this
in Java 1.0.
8.       Applets cannot define or use a new instance of ClassLoader, SecurityManager, ContentHandlerFactory, SocketImplFactory, or URLStreamHandlerFactory. They must use the ones already in place.

9.      An applet can only open network connections to the host from which the applet itself was downloaded.
10.  An applet cannot listen on ports below 1,024. (Internet Explorer 5.0 doesn't
allow applets to listen on any ports.)
11.  Even if an applet can listen on a port, it can accept incoming connections only
from the host from which the applet itself was downloaded.


















The Network Methods of java.applet.Applet

Using java.applet.Applet to Download Data
  • Sound
  • Images

public URL getDocumentBase( )
The getDocumentBase( ) method returns the URL of the page containing the applet.

Example
import java.applet.*;
import java.awt.*;
public class WhereAmI extends Applet {
public void paint (Graphics g) {
g.drawString(this.getDocumentBase().toString( ), 25, 50);
}
}
public URL getCodeBase( )
The getCodeBase( ) method returns the URL of the directory where the applet is
located. If the applet is in a JAR archive, then the codebase is the URL of the directory where the JAR archive is. If the applet is in a package (e.g.com.macfaq.applets.MyApplet instead of just MyApplet), then the codebase is the directory or JAR archive containing the outermost package such as com.

Downloading Images
public Image getImage(URL url)
Image myLogo = getImage (new URL("http://metalab.unc.edu/java/cup.gif"));


public Image getImage(URL url, String name)
Image logo = this.getImage(new URL("http://metalab.unc.edu/java/"),
"cup.gif");

Example
public class ImageView extends Applet {
Image picture;
public void init( ) {
try {
URL u = new URL(this.getCodeBase( ), this.getParameter("IMAGE"));
this.picture = this.getImage(u);
System.err.println(u);
}
catch (MalformedURLException e) {
// shouldn't happen, the codebase is never malformed
}
}
public void paint (Graphics g) {
g.drawImage(this.picture, 0, 0, this);
}
}

Note:
The getImage( ) method returns immediately, even before it knows whether the
image actually exists. The image isn't loaded until some other part of the program
actually tries to draw it, or you explicitly force the image to start loading

Downloading Sounds
public void play(URL u)
The play( ) method looks for a sound file at the URL u. If the sound file is found, then it is downloaded and played. Otherwise, nothing happens.
Example
try {
URL soundLocation =
new URL( "http://metalab.unc.edu/java/course/week9/spacemusic.au" );
play(soundLocation);
}
catch (MalformedURLException e) {
System.err.println(

Example
import java.applet.*;
import java.awt.*;
import java.net.*;
public class PlaySound extends Applet {
public void init( ) {
try {
URL u = new URL(this.getCodeBase( ), this.getParameter("sound"));
this.play(u);
}
catch (MalformedURLException e) {}

}
}

public void play(URL url, String filename)
This is similar to the previous method, except that it uses the url argument to find the sound file's directory and the filename argument to get the actual filename. For
Example:
play(new URL("http://www.macfaq.com/", "gong.au"));

public AudioClip getAudioClip(URL u)
The java.applet.AudioClip interface represents a sound. You can download a sound from a web site with the getAudioClip( ) method. Once you have an AudioClip object, play it at your leisure by calling the clip's play( ) and loop( ) methods; play( ) plays the file once, and loop( ) plays it repeatedly. Both of these methods let you keep the audio clip around for future use—unlike the play( ) method of the last section, which discarded the audio data after it had finished.

Example
AudioClip theGong;
try {
URL u = new URL(http://metalab.unc.edu/javafaq/gong.au);
theGong = this.getAudioClip(u);
theGong.loop();
//theGong.play();

}
catch (MalformedURLException e) {
System.err.println(e);
}
public AudioClip getAudioClip(URL url, String filename)

Example
import java.applet.*;
import java.awt.*;
public class RelativeBeep extends Applet implements Runnable {

private AudioClip beep;
private boolean stopped = false;

public void init( ) {
beep = this.getAudioClip(this.getDocumentBase( ),"sounds/beep.au");
if (beep != null) {
Thread t = new Thread(this);
t.start( );
}
}
public void start( ) {
this.stopped = false;
}
public void stop( ) {
this.stopped = true;
}
public void run( ) {
Thread.currentThread( ).setPriority(Thread.MIN_PRIORITY);
while (true) {
if (!stopped) beep.play( );
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {}

The MediaTracker Class

1.       This class is used for loading multiple images.
2.       The java.awt.MediaTracker class can track the loading status of many different images and organize them into logical groups.
3.  Create an instance of MediaTracker and then use the MediaTracker's addImage(Image pic, int ID ) method for each Image.
4.      ID does not have to be unique; it is really a group ID that is used to organize different images into groups.
5.      Before using the image, call a method such as checkID( ) to see whether the image is ready.
6.       Other methods let you force loading to start, discover which images in a group have failed to load successfully, wait for images to finish loading, and so on.

7.      The Constructor
The MediaTracker class has one constructor:
public MediaTracker(Component comp)
This constructor creates a MediaTracker object that tracks images for a specified Component. It's usually invoked like this:
MediaTracker tracker = new MediaTracker(this);

8.      Adding Images to MediaTrackers
Image picture = this.getImage(this.getDocumentBase( ), "logo.gif");
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(picture, 1);
public void addImage(Image image, int id, int width, int height)
The image will eventually be displayed scaled to the width ‘width’ and the height ‘height’.

9.      Checking Whether Media Has Loaded

There are four check methods that tell you whether particular images tracked by a
MediaTracker have loaded. These are:
public boolean checkID(int id)
public boolean checkID(int id, boolean load)
public boolean checkAll( )
public boolean checkAll(boolean load)

10.  public boolean checkID(int id)
This method checks whether all the images with the indicated ID that are tracked by
this MediaTracker have finished loading. If they have, it returns true; otherwise, it
returns false. Multiple Image objects may have the same ID.




public void paint(Graphics g) {
if (theTracker.checkID(1)) {
g.drawImage(thePicture, 0, 0, this);
}
else {
g.drawString("Loading Picture. Please hang on", 25, 50);
}
}
11.  public boolean checkID(int id, boolean load)
This method checks whether all the Image objects with the indicated ID that are tracked by this MediaTracker have finished loading. If they have, it returns true; otherwise, it returns false. Multiple Image objects may have the same ID. If the boolean argument load is true, all images with that ID that are not yet being loaded will begin loading.

public void paint(Graphics g) {
if (theTracker.checkID(1, true)) {
g.drawImage(thePicture, 0, 0, this);
}
else {
g.drawString("Loading Picture. Please hang on", 25, 50);
}
}
12.  public boolean checkAll( )
This method checks whether all the Image objects that are tracked by this object have
finished loading. ID numbers are not considered. If all images are loaded, it returns
true; otherwise, it returns false. It does not start loading images that are not already
loading.

13.  public boolean checkAll(boolean load)
This version of checkAll( ) checks whether all the Image objects that are tracked by
this MediaTracker have finished loading. If they have, it returns true; otherwise, it
returns false. If the boolean argument load is true, then it also starts loading any
Image objects that are not already being loaded.

14.  public void waitForID(int id) throws InterruptedException
This method forces the images with the ID number id that are tracked by this
MediaTracker to start loading and then waits until each one has either finished
loading, aborted, or received an error.

try {
tracker.waitForID(1);
}
catch (InterruptedException e) {
}
15.  public boolean waitForAll( ) throws InterruptedException
The waitForAll( ) method starts loading all the images that are tracked by this
MediaTracker in up to four separate threads while pausing the thread that invoked it
until each tracked image has either finished loading, aborted, or received an error. An
InterruptedException is thrown if another thread interrupts the waiting thread.

Downloading the images is easy
à           Create URL objects that point to each image.
à           Then call Applet’s ‘Image getImage( )’ with each URL.
à           Add returned image to MediaTracker Object.
à           Use it (MediaTracker) to force the images to load;
à           Then use waitForAll( ) to make sure all frames have loaded.
à           Finally, call drawImage( ) method of class Graphics
to display the images in sequence.


Example A Very Simple Animator Applet

public class Animator extends Applet
implements Runnable, MouseListener {
private boolean running = false;
private int currentCell = 0;
private Vector cells = new Vector( );
private MediaTracker tracker;

public void init( ) {
this.addMouseListener(this);
String nextCell;
this.tracker = new MediaTracker(this);

for (int i = 0; (nextCell = this.getParameter("Cell" + i)) != null; i++) {
Image img = this.getImage(this.getDocumentBase( ), nextCell);
cells.addElement(img);
tracker.addImage(img, i);
// start loading the image in a separate thread
tracker.checkID(i, true);
}
}
public void run( ) {
// wait for all images to finish loading
try {
this.tracker.waitForAll( );
}
catch (InterruptedException e) {
}
for (currentCell=0; currentCell < cells.size( ); currentCell++)
{
if (!running) return;
// paint the cell
this.repaint( );
// sleep for a tenth of a second
// i.e. play ten frames a second

try {
Thread.sleep(100);
}
catch (InterruptedException ie) {}
}
}
public void stop( ) {
this.running = false;
}
public void start( ) {
this.running = true;
Thread play = new Thread(this);
play.start( );
}
public void paint(Graphics g) {
g.drawImage((Image) cells.elementAt(currentCell), 0, 0, this);
}
// The convention is that a mouseClick starts
// a stopped applet and stops a running applet.
public void mouseClicked(MouseEvent e) {
if (running) {
this.stop( );
}
else {
this.start( );
}
}
// do-nothing methods required to implement the MouseListener
interface
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}